hdu 4681 String (动态规划-最长公共子序列)
2013-08-15 19:07
369 查看
1、http://acm.hdu.edu.cn/showproblem.php?pid=4681
2、题目大意
给定3个字符串a,b,c,求一个字符串d,使得d是a.b 的子序列(在ab中不一定是连续的),c是d的子字符串(c是连续的),首先找出ab字符串对应的d的区间,然后枚举区间,求前后两端的最长公共子序列,代码超时了。。。
看了网上的代码,终于知道为什么错了,dp[][]可以预处理,没必要每次都调用DP()
3、题目
Total Submission(s): 153 Accepted Submission(s): 67
[align=left]Problem Description[/align]
Given 3 strings A, B, C, find the longest string D which satisfy the following rules:
a) D is the subsequence of A
b) D is the subsequence of B
c) C is the substring of D
Substring here means a consecutive subsequnce.
You need to output the length of D.
[align=left]Input[/align]
The first line of the input contains an integer T(T = 20) which means the number of test cases.
For each test case, the first line only contains string A, the second line only contains string B, and the third only contains string C.
The length of each string will not exceed 1000, and string C should always be the subsequence of string A and string B.
All the letters in each string are in lowercase.
[align=left]Output[/align]
For each test case, output Case #a: b. Here a means the number of case, and b means the length of D.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
4、AC代码:‘
4、超时的代码:
2、题目大意
给定3个字符串a,b,c,求一个字符串d,使得d是a.b 的子序列(在ab中不一定是连续的),c是d的子字符串(c是连续的),首先找出ab字符串对应的d的区间,然后枚举区间,求前后两端的最长公共子序列,代码超时了。。。
看了网上的代码,终于知道为什么错了,dp[][]可以预处理,没必要每次都调用DP()
3、题目
String
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 153 Accepted Submission(s): 67
[align=left]Problem Description[/align]
Given 3 strings A, B, C, find the longest string D which satisfy the following rules:
a) D is the subsequence of A
b) D is the subsequence of B
c) C is the substring of D
Substring here means a consecutive subsequnce.
You need to output the length of D.
[align=left]Input[/align]
The first line of the input contains an integer T(T = 20) which means the number of test cases.
For each test case, the first line only contains string A, the second line only contains string B, and the third only contains string C.
The length of each string will not exceed 1000, and string C should always be the subsequence of string A and string B.
All the letters in each string are in lowercase.
[align=left]Output[/align]
For each test case, output Case #a: b. Here a means the number of case, and b means the length of D.
[align=left]Sample Input[/align]
2 aaaaa aaaa aa abcdef acebdf cf
[align=left]Sample Output[/align]
Case #1: 4 Case #2: 3
4、AC代码:‘
#include<stdio.h> #include<algorithm> using namespace std; #include<string.h> #define N 1005 char a ; char b ; char c ; int tsa ; int tea ; int tsb ; int teb ; struct node { int s; int e; } ansa ,ansb ; int dp1 ,dp2 ; int la,lb,lc; char transa ,transb ; void DP() { memset(dp1,0,sizeof(dp1)); for(int i=1; i<=la; i++) { for(int j=1; j<=lb; j++) { if(a[i-1]==b[j-1]) dp1[i][j]=dp1[i-1][j-1]+1; else dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]); } } memset(dp2,0,sizeof(dp2)); int j=0; for(int i=la-1;i>=0;i--) transa[j++]=a[i]; j=0; for(int i=lb-1;i>=0;i--) transb[j++]=b[i]; for(int i=1; i<=la; i++) { //printf("aa.e=%d %d\n",aa.e,la); for(int j=1; j<=lb; j++) { if(transa[i-1]==transb[j-1]) dp2[i][j]=dp2[i-1][j-1]+1; else dp2[i][j]=max(dp2[i-1][j],dp2[i][j-1]); } } } int main() { int t,cas=0; scanf("%d",&t); while(t--) { cas++; int maxx=-999999; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%s%s%s",a,b,c); lc=strlen(c); la=strlen(a); lb=strlen(b); int ta=0,tb=0,k; for(int i=0;i<la;i++) { if(a[i]==c[0]) { k=1; int flag=0; for(int j=i+1;j<la;j++) { if(a[j]==c[k]) k++; if(k==lc) { flag=j; break; } } if(flag!=0) { ansa[ta].s=i; ansa[ta++].e=flag; } } } for(int i=0;i<lb;i++) { if(b[i]==c[0]) { k=1; int flag=0; for(int j=i+1;j<lb;j++) { if(b[j]==c[k]) k++; if(k==lc) { flag=j; break; } } if(flag!=0) { ansb[tb].s=i; ansb[tb++].e=flag; } } } DP(); for(int i=0; i<ta; i++) { for(int j=0; j<tb; j++) { //printf("**%d %d %d %d\n",ansa[i].s,ansa[i].e,ansb[j].s,ansb[j].e); //DP(ansa[i],ansb[j]); maxx=max(maxx,dp1[ansa[i].s][ansb[j].s]+dp2[la-1-ansa[i].e][lb-1-ansb[j].e]); } } printf("Case #%d: %d\n",cas,maxx+lc); } return 0; }
4、超时的代码:
#include<stdio.h> #include<algorithm> using namespace std; #include<string.h> #define N 1005 char a ; char b ; char c ; int tsa ; int tea ; int tsb ; int teb ; struct node { int s; int e; } ansa ,ansb ; int dp ; int la,lb,lc; int maxx=-99999; void DP(node aa,node bb) { int l=max(aa.s,bb.s); int tp1=0,tp2=0; memset(dp,0,sizeof(dp)); for(int i=1; i<=aa.s; i++) { for(int j=1; j<=bb.s; j++) { if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } tp1=dp[aa.s][bb.s]; // printf("tp1=%d\n",tp1); l=max((la-aa.e),(lb-bb.e)); memset(dp,0,sizeof(dp)); for(int i=aa.e+1; i<la; i++) { //printf("aa.e=%d %d\n",aa.e,la); for(int j=bb.e+1; j<lb; j++) { if(a[i]==b[j]) dp[i-aa.e][j-bb.e]=dp[i-1-aa.e][j-1-bb.e]+1; else dp[i-aa.e][j-bb.e]=max(dp[i-1-aa.e][j-bb.e],dp[i-aa.e][j-1-bb.e]); } } tp2=dp[la-aa.e][lb-bb.e]; //printf("tp2=%d\n",tp2); if(tp1+tp2>maxx) maxx=tp1+tp2; } int finda(int s,int e) { int j=0; for(int i=s; i<=e; i++) { if(a[i]==c[j]) j++; } if(j==lc) return 1; return 0; } int findb(int s,int e) { int j=0; for(int i=s; i<=e; i++) { if(b[i]==c[j]) j++; } if(j==lc) return 1; return 0; } int main() { int t,cas=0; scanf("%d",&t); while(t--) { cas++; maxx=-999999; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); scanf("%s%s%s",a,b,c); lc=strlen(c); la=strlen(a); lb=strlen(b); char tmp1=c[0]; char tmp2=c[lc-1]; int sa=0,ea=0; int maxl=max(la,lb); int sb=0,eb=0; for(int i=0; i<maxl; i++) { if(a[i]==tmp1) tsa[sa++]=i; if(a[i]==tmp2) tea[ea++]=i; if(b[i]==tmp1) tsb[sb++]=i; if(b[i]==tmp2) teb[eb++]=i; } int k=0; for(int i=0; i<sa; i++) { for(int j=0; j<ea; j++) { if(finda(tsa[i],tea[j])) { ansa[k].s=tsa[i]; ansa[k].e=tea[j]; k++; } } } int l=0; for(int i=0; i<sb; i++) { for(int j=0; j<eb; j++) { if(findb(tsb[i],teb[j])) { ansb[l].s=tsb[i]; ansb[l].e=teb[j]; l++; } } } for(int i=0; i<k; i++) { for(int j=0; j<l; j++) { //printf("**%d %d %d %d\n",ansa[i].s,ansa[i].e,ansb[j].s,ansb[j].e); DP(ansa[i],ansb[j]); } } printf("Case #%d: %d\n",cas,maxx+lc); } return 0; }
相关文章推荐
- HDU 4681 String (最长公共子序列)
- hdu 4681 String/杭电多校第八场1006 最长公共子序列长
- hdu 1159 Common Subsequence(动态规划:最长公共子序列)
- DP动态规划——hdu 1008 Common Subsequence(最长公共子序列)
- HDU 1243 反恐训练营 (动态规划求最长公共子序列)
- HDU 1159(动态规划-最长公共子序列)
- HDU 4681 string 求最长公共子序列的简单DP+暴力枚举
- HDU 1243 反恐训练营 (动态规划求最长公共子序列)
- DP动态规划——hdu 1008 Common Subsequence(最长公共子序列)
- HDU 4681 String 最长公共子序列
- 动态规划解最长公共子序列问题
- 第十五章动态规划之“最长公共子序列”
- 动态规划 最长公共子序列
- HDU 4681 String(DP)
- hdu 1003 (动态规划入门)Max Sum
- 动态规划——最长公共子序列 公共子串 POJ1458
- 动态规划(DP计数):HDU 5121 Just A Mistake
- 动态规划5_最长公共子序列
- 动态规划之最长公共子序列 (LCS )
- 动态规划: HDU 1789Doing Homework again