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 ...
随机推荐
- .net学习之进程外Session的配置
转载地址:http://www.cnblogs.com/rohelm/archive/2012/05/13/2498465.html 人人都知道怎么去使用session,但是初学者,尤其是自学的学生可 ...
- Delphi ini文件读写
参考:http://www.cnblogs.com/zhangzhifeng/archive/2011/12/01/2270267.html 一.ini文件的结构 ;这是关于 ini 文件的注释 [节 ...
- Big Data, MapReduce, Hadoop, and Spark with Python
此书不错,很短,且想打通PYTHON和大数据架构的关系. 先看一次,计划把这个文档作个翻译. 先来一个模拟MAPREDUCE的东东... mapper.py class Mapper: def map ...
- OCJP(1Z0-851) 模拟题分析(八)over
Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...
- golang channel buffer
package mainimport ( "fmt" "time")func main() { // Case-1: no buffer //chanMessa ...
- Linux命令之ar - 创建静态库.a文件和动态库.so
转自:http://blog.csdn.net/eastonwoo/article/details/8241693 用途说明 创建静态库.a文件.用C/C++开发程序时经常用到,但我很少单独在命令行中 ...
- 【转】从RGB色转为灰度色算法
----本文摘自作者ZYL910的博客 一.基础 对于彩色转灰度,有一个很著名的心理学公式: Gray = R*0.299 + G*0.587 + B*0.114 二.整数算法 而实际应用时,希望避 ...
- IplImage, CvMat, Mat 的关系
IplImage, CvMat, Mat 的关系 转载来源:http://www.cnblogs.com/summerRQ/articles/2406109.html opencv中常见的与图像操作有 ...
- ImageSpan
自定义ImageSpan继承类,可以设置图片大小和位置 import android.content.Context; import android.graphics.Bitmap; import a ...
- 【转】使用Apache Kylin搭建企业级开源大数据分析平台
http://www.thebigdata.cn/JieJueFangAn/30143.html 本篇文章整理自史少锋4月23日在『1024大数据技术峰会』上的分享实录:使用Apache Kylin搭 ...