这题确实很棒。。又是无想法。。其实是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)的更多相关文章

  1. Common Subsequence(dp)

    Common Subsequence Time Limit: 2 Sec  Memory Limit: 64 MBSubmit: 951  Solved: 374 Description A subs ...

  2. UVA 10405 Longest Common Subsequence (dp + LCS)

    Problem C: Longest Common Subsequence Sequence 1: Sequence 2: Given two sequences of characters, pri ...

  3. POJ1458 Common Subsequence —— DP 最长公共子序列(LCS)

    题目链接:http://poj.org/problem?id=1458 Common Subsequence Time Limit: 1000MS   Memory Limit: 10000K Tot ...

  4. Codeforces Round#201(div1) D. Lucky Common Subsequence

    题意:给定两个串,求出两个串的最长公共子序列,要求该公共子序列不包含virus串. 用dp+kmp实现 dp[i][j][k]表示以i结尾的字符串和以j结尾的字符串的公共子序列的长度(其中k表示该公共 ...

  5. POJ - 1458 Common Subsequence DP最长公共子序列(LCS)

    Common Subsequence A subsequence of a given sequence is the given sequence with some elements (possi ...

  6. Longest Common Subsequence (DP)

    Given two strings, find the longest common subsequence (LCS). Your code should return the length of  ...

  7. HDU 1159 Common Subsequence --- DP入门之最长公共子序列

    题目链接 基础的最长公共子序列 #include <bits/stdc++.h> using namespace std; ; char c[maxn],d[maxn]; int dp[m ...

  8. POJ 1458 Common Subsequence DP

    http://poj.org/problem?id=1458 用dp[i][j]表示处理到第1个字符的第i个,第二个字符的第j个时的最长LCS. 1.如果str[i] == sub[j],那么LCS长 ...

  9. HDU 1159 Common Subsequence【dp+最长公共子序列】

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. 重温WCF之WCF中可靠性会话(十四)

    1.WCF中可靠性会话在绑定层保证消息只会被传输一次,并且保证消息之间的顺序.当使用TCP(Transmission Control Protocol,传输控制协议)通信时,协议本身保证了可靠性.然而 ...

  2. Delphi数组

    参考:http://www.cnblogs.com/huangjacky/archive/2009/12/21/1628833.html 数组就是一堆相同特性数据的一个组合,也就是每个元素的类型必须是 ...

  3. Shell编程基础教程3--Shell输入与输出

    3.Shell输入与输出    3.1.echo        echo命令可以显示文本行或变量,或者把字符串输出到文件        echo [option] string             ...

  4. HDU5558 Alice's Classified Message(合肥区域赛 后缀数组)

    当初合肥区域赛的题(现场赛改了数据范围就暴力过了),可惜当初后缀数组算法的名字都没听过,现在重做下. i从1到n - 1,每次枚举rank[i]附近的排名,并记录当起点小于i时的LCP(rank[i] ...

  5. [译] Extending jQuery Part1 Simple extensions

    本章包含: JQuery 的起源和目标. 你能扩展JQuery 的那些部分. JQuery 扩展的实例. 如今,JQuery 已经是网络上最受欢迎的JavaScript Library. 1.1 jQ ...

  6. Oracle 数据泵文件

    数据泵文件 expdp介绍 EXPDP命令行选项1. ATTACH该选项用于在客户会话与已存在导出作用之间建立关联.语法如下ATTACH=[schema_name.]job_nameSchema_na ...

  7. [荐]使用Js操作注册表

    使用Js操作注册表 要操作注册表需要通过ActiveX控件调用WScript.shell对象,通过该对象的一些方法来操作. WshShell对象:可以在本地运行程序.操纵注册表内容.创建快捷方式或访问 ...

  8. Android:dimen尺寸资源文件的使用(转)

    为了适配不同的分辨率. dimen.xml在values文件夹下面 <resources> <!-- Default screen margins, per the Android ...

  9. torch7安装

    按照官网进行安装即可;(http://torch.ch/docs/getting-started.html#_) # in a terminal, run the commands WITHOUT s ...

  10. 常用eclipse 快捷键

    Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当 ...