CF 346B. Lucky Common Subsequence(DP+KMP)
这题确实很棒。。又是无想法。。其实是AC自动机+DP的感觉,但是只有一个串,用kmp就行了。
dp[i][j][k],k代表前缀为virus[k]的状态,len表示其他所有状态串,处理出Ac[len][26]数组来,DP就可以了。状态转移那里一直没想清楚,wa了很多次,记录路径倒是不复杂,瞎搞搞就行。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
char s1[],s2[],virus[];
int dp[][][];
int pre[][][];
int pre1[][][];
int Ac[][];
int next[];
char ans[];
void kmp()
{
int i,j,len,temp;
len = strlen(virus);
next[] = -;
j = -;
for(i = ; i < len; i ++)
{
while(j >= &&virus[j+] != virus[i])
j = next[j];
if(virus[j+] == virus[i]) j ++;
next[i] = j;
}
for(i = ; i < len; i ++)
{
for(j = ; j < ; j ++)
{
temp = i;
while(temp >= &&virus[temp+] != 'A'+j)
temp = next[temp];
if(virus[temp+] == 'A' + j) temp ++;
if(temp == -)
Ac[i][j] = len;
else
Ac[i][j] = temp;
}
}
for(i = ; i < ; i ++)
{
if(i + 'A' == virus[])
Ac[len][i] = ;
else
Ac[len][i] = len;
}
}
int main()
{
int i,j,k,len1,len2,len,maxz,a,b,kk;
scanf("%s%s%s",s1,s2,virus);
len1 = strlen(s1);
len2 = strlen(s2);
len = strlen(virus);
kmp();
for(i = ; i <= len1; i ++)
{
for(j = ; j <= len2; j ++)
{
for(k = ; k <= len; k ++)
{
if(k == len-) continue;
if(dp[i][j][k] < dp[i-][j][k])
{
dp[i][j][k] = dp[i-][j][k];
pre[i][j][k] = ;
pre1[i][j][k] = k;
}
if(dp[i][j][k] < dp[i][j-][k])
{
dp[i][j][k] = dp[i][j-][k];
pre[i][j][k] = ;
pre1[i][j][k] = k;
}
if(s1[i-] == s2[j-])
{
if(Ac[k][s1[i-]-'A'] == len-) continue;
else if(dp[i][j][Ac[k][s1[i-]-'A']] < dp[i-][j-][k] + )
{
dp[i][j][Ac[k][s1[i-]-'A']] = dp[i-][j-][k] + ;
pre[i][j][Ac[k][s1[i-]-'A']] = ;
pre1[i][j][Ac[k][s1[i-]-'A']] = k;
}
}
}
}
}
maxz = ;
for(i = ; i <= len1; i ++)
{
for(j = ; j <= len2; j ++)
{
for(k = ; k <= len; k ++)
{
if(maxz < dp[i][j][k])
{
maxz = dp[i][j][k];
a = i;
b = j;
kk = k;
}
}
}
}
if(maxz == )
{
printf("0\n");
return ;
}
int num = ;
//printf("%d\n",maxz);
while(a != &&b != )
{
if(pre[a][b][kk] == )
{
ans[num++] = s1[a-];
kk = pre1[a][b][kk];
a --;
b --;
}
else if(pre[a][b][kk] == )
{
kk = pre1[a][b][kk];
a --;
}
else if(pre[a][b][kk] == )
{
kk = pre1[a][b][kk];
b --;
}
else
break;
}
for(i = num-; i >= ; i --)
{
printf("%c",ans[i]);
}
printf("\n");
return ;
}
CF 346B. Lucky Common Subsequence(DP+KMP)的更多相关文章
- Common Subsequence(dp)
Common Subsequence Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 951 Solved: 374 Description A subs ...
- UVA 10405 Longest Common Subsequence (dp + LCS)
Problem C: Longest Common Subsequence Sequence 1: Sequence 2: Given two sequences of characters, pri ...
- POJ1458 Common Subsequence —— DP 最长公共子序列(LCS)
题目链接:http://poj.org/problem?id=1458 Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Tot ...
- Codeforces Round#201(div1) D. Lucky Common Subsequence
题意:给定两个串,求出两个串的最长公共子序列,要求该公共子序列不包含virus串. 用dp+kmp实现 dp[i][j][k]表示以i结尾的字符串和以j结尾的字符串的公共子序列的长度(其中k表示该公共 ...
- POJ - 1458 Common Subsequence DP最长公共子序列(LCS)
Common Subsequence A subsequence of a given sequence is the given sequence with some elements (possi ...
- Longest Common Subsequence (DP)
Given two strings, find the longest common subsequence (LCS). Your code should return the length of ...
- HDU 1159 Common Subsequence --- DP入门之最长公共子序列
题目链接 基础的最长公共子序列 #include <bits/stdc++.h> using namespace std; ; char c[maxn],d[maxn]; int dp[m ...
- POJ 1458 Common Subsequence DP
http://poj.org/problem?id=1458 用dp[i][j]表示处理到第1个字符的第i个,第二个字符的第j个时的最长LCS. 1.如果str[i] == sub[j],那么LCS长 ...
- HDU 1159 Common Subsequence【dp+最长公共子序列】
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
随机推荐
- JavaWeb学习之转发和重定向、会话技术:cookie、session、验证码实例、URLConnection使用(下载网页)(4)
1.转发和重定向 HttpServletResponse response 转发: RequestDispatcher dispatcher = request.getRequestDispatche ...
- Linux进程状态 ( Linux Process State Codes)
进程状态代码及说明: STATE代码 说明 D 不可中断的睡眠. 通常是处于I/O之中. R 运行中/可运行. 正处于运行队列中. S 可中断的睡眠. 等待某事件发生. T 已停止. 可能是因为she ...
- 数据结构之图 Part2 - 1
邻接矩阵 网上很少有C# 写图的数据结构的例子,实际的项目中也从来没用过Array 这坨东西,随手写个,勿喷. namespace LH.GraphConsole { public struct Gr ...
- html5 简单音乐播放器
html5 简单音乐播放器 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> < ...
- Active Record 数据库模式-增删改查操作
选择数据 下面的函数帮助你构建 SQL SELECT语句. 备注:如果你正在使用 PHP5,你可以在复杂情况下使用链式语法.本页面底部有具体描述. $this->db->get(); 运行 ...
- 1.ok6410移植bootloader,移植u-boot,学习u-boot命令
ok6410移植u-boot 既然是移植u-boot当然首先需要u-boot源码,这里的u-boot代码是由国嵌提供的. 一.配置编译u-boot A. 解压 u-boot 压缩文件 B. 进入解压生 ...
- LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)
LeetCode 39 class Solution { public: void dfs(int dep, int maxDep, vector<int>& cand, int ...
- 编译器 expected unqualified-id before numeric constant 错误
今天调试代码,碰到expected unqualified-id before numeric constant 错误,代码的错误模块出现在一个函数模块上, 奇怪的是这个函数模块之前编译了很多次,也没 ...
- 编写css相关注意事项以及小技巧
一.小技巧 1.对于开始写网站css之前一般都要对css进行重置(养成写注释的习惯): ;;} body{font-size:16px;} img{border:none;} li{list-styl ...
- VS链接过程中与MSVCRT.lib冲突
vs代码生成有/MT,/MTd,/Md,/MDd四个编译选项,分别代表多线程.多线程调试.多线程DLL.多线程调试DLL. 编译时引用的lib分别为libcmt.li.libcmtd.lib.msvc ...