Codeforces Round#201(div1) D. Lucky Common Subsequence
2014-09-09 19:14
701 查看
题意:给定两个串,求出两个串的最长公共子序列,要求该公共子序列不包含virus串。
用dp+kmp实现
dp[i][j][k]表示以i结尾的字符串和以j结尾的字符串的公共子序列的长度(其中k表示该公共子序列的与virus的匹配程度)很显然,当k==strlen(virus)时,该公共子序列不是我们所求得
当添加一个字符时,如果失配,这时不能让k直接等于0,而是要用kmp给k一个合理的值。
View Code
用dp+kmp实现
dp[i][j][k]表示以i结尾的字符串和以j结尾的字符串的公共子序列的长度(其中k表示该公共子序列的与virus的匹配程度)很显然,当k==strlen(virus)时,该公共子序列不是我们所求得
当添加一个字符时,如果失配,这时不能让k直接等于0,而是要用kmp给k一个合理的值。
#include <stdio.h> #include <string.h> const int N = 100 + 10; int dp ; int pre [3]; char s1 ,s2 ,vir ; int next ; char ans ; void makeNext(int n) { next[0] = -1; int i = 0,j=-1; while(i < n) { if(j==-1 || vir[i] == vir[j]) { i++; j++; next[i] = j; } else j = next[j]; } } void DP(int x, int y, int z, int x1, int y1, int z1, int val) { if(dp[x][y][z] < dp[x1][y1][z1] + val) { dp[x][y][z] = dp[x1][y1][z1] + val;//状态转移 //保存路径 pre[x][y][z][0] = x1; pre[x][y][z][1] = y1; pre[x][y][z][2] = z1; } } int main() { int i,j,k; scanf("%s%s%s",s1+1,s2+1,vir); int len1 = strlen(s1+1); int len2 = strlen(s2+1); int len3 = strlen(vir); memset(dp,0,sizeof(dp)); memset(pre,-1,sizeof(pre)); makeNext(len3); for(i=1; i<=len1; ++i) for(j=1; j<=len2; ++j) { for(k=0; k<len3; ++k) { DP(i,j,k,i-1,j,k,0);//s1[i] != s2[j]时的转移 DP(i,j,k,i,j-1,k,0); if(s1[i] == s2[j])//s1[i] == s2[j] { if(s1[i] == vir[k]) { DP(i,j,k+1,i-1,j-1,k,1); } else { int p = next[k]; while(p!=-1 && s1[i] != vir[p]) p = next[p]; if(p==-1) p = 0; if(s1[i] == vir[p]) DP(i,j,p+1,i-1,j-1,k,1); else DP(i,j,p,i-1,j-1,k,1); } } } } int z; int Max = -1; for(k=0; k<len3; ++k) if(Max < dp[len1][len2][k]) { Max = dp[len1][len2][k]; z = k; } if(Max <= 0) printf("0\n"); else//根据路径求出最长公共子序列 { int tMax = Max; int x = len1,y = len2; while(pre[x][y][z][0] != -1) { int xx = pre[x][y][z][0]; int yy = pre[x][y][z][1]; int zz = pre[x][y][z][2]; if(x-xx==1 && y-yy==1&&s1[x] == s2[y]) ans[Max--] = s1[x]; x = xx;y=yy;z=zz; } for(i=1; i<=tMax; ++i) printf("%c",ans[i]); printf("\n"); } }
View Code
相关文章推荐
- codeforce Round201 div1 B. Lucky Common Subsequence KMP+DP
- Code Forces Round 201 B Lucky Common Subsequence 拓展提问
- Codeforces 346 B. Lucky Common Subsequence
- Codeforces 346B - Lucky Common Subsequence kmpDP
- codeforces 347 D Lucky Common Subsequence(dp+kmp)
- Codeforces 347D - Lucky Common Subsequence
- HDU 1423 Greatest Common Increasing Subsequence——dp
- hdu 1159 Common Subsequence(lcs)
- HDU-1159 Common Subsequence(最长公共子序列)
- 杭电1423(Greatest Common Increasing Subsequence)
- [POJ] 1458 -> Common Subsequence
- HDU 1423 Greatest Common Increasing Subsequence LCIS
- SRM 510 D2L3:TheLuckyBasesDivTwo,brute force,optimization
- POJ1458--Common Subsequence(dp)
- [POJ]1458 Common Subsequence
- Codeforces Round #183 (Div. 1)Lucky Permutation Triple
- HDU 1159 Common Subsequence (LCS)
- UVA 10405 - Longest Common Subsequence
- UVa 10405 - Longest Common Subsequence
- POJ 1458 Common Subsequence