这题确实很棒。。又是无想法。。其实是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. JavaWeb学习之转发和重定向、会话技术:cookie、session、验证码实例、URLConnection使用(下载网页)(4)

    1.转发和重定向 HttpServletResponse response 转发: RequestDispatcher dispatcher = request.getRequestDispatche ...

  2. Linux进程状态 ( Linux Process State Codes)

    进程状态代码及说明: STATE代码 说明 D 不可中断的睡眠. 通常是处于I/O之中. R 运行中/可运行. 正处于运行队列中. S 可中断的睡眠. 等待某事件发生. T 已停止. 可能是因为she ...

  3. 数据结构之图 Part2 - 1

    邻接矩阵 网上很少有C# 写图的数据结构的例子,实际的项目中也从来没用过Array 这坨东西,随手写个,勿喷. namespace LH.GraphConsole { public struct Gr ...

  4. html5 简单音乐播放器

    html5 简单音乐播放器 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> < ...

  5. Active Record 数据库模式-增删改查操作

    选择数据 下面的函数帮助你构建 SQL SELECT语句. 备注:如果你正在使用 PHP5,你可以在复杂情况下使用链式语法.本页面底部有具体描述. $this->db->get(); 运行 ...

  6. 1.ok6410移植bootloader,移植u-boot,学习u-boot命令

    ok6410移植u-boot 既然是移植u-boot当然首先需要u-boot源码,这里的u-boot代码是由国嵌提供的. 一.配置编译u-boot A. 解压 u-boot 压缩文件 B. 进入解压生 ...

  7. 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 ...

  8. 编译器 expected unqualified-id before numeric constant 错误

    今天调试代码,碰到expected unqualified-id before numeric constant 错误,代码的错误模块出现在一个函数模块上, 奇怪的是这个函数模块之前编译了很多次,也没 ...

  9. 编写css相关注意事项以及小技巧

    一.小技巧 1.对于开始写网站css之前一般都要对css进行重置(养成写注释的习惯): ;;} body{font-size:16px;} img{border:none;} li{list-styl ...

  10. VS链接过程中与MSVCRT.lib冲突

    vs代码生成有/MT,/MTd,/Md,/MDd四个编译选项,分别代表多线程.多线程调试.多线程DLL.多线程调试DLL. 编译时引用的lib分别为libcmt.li.libcmtd.lib.msvc ...