hdu 4681 最长公共子序列+枚举
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4681
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int maxn = 1010; const int INF = 0x3f3f3f; char a[maxn],b[maxn],c[maxn]; int dp1[maxn][maxn]; int dp2[maxn][maxn]; void Lcs1(char* s1,char* s2,int m,int n){ for(int i=1;i<=m;i++) for(int j=1;j<=n;j++){ if(s1[i-1] == s2[j-1]) dp1[i][j] = dp1[i-1][j-1] + 1; else if(dp1[i-1][j]>dp1[i][j-1]) dp1[i][j] = dp1[i-1][j]; else dp1[i][j] = dp1[i][j-1]; } } void Lcs2(char* s1,char* s2,int m,int n){ for(int i=m-2;i>=0;i--) for(int j=n-2;j>=0;j--){ if(s1[i+1] == s2[j+1]) dp2[i][j] = dp2[i+1][j+1] + 1; else if(dp2[i+1][j]>dp2[i][j+1]) dp2[i][j] = dp2[i+1][j]; else dp2[i][j] = dp2[i][j+1]; } } int main() { //freopen("E:\\acm\\input.txt","r",stdin); int T; scanf("%d",&T); for(int t=1;t<=T;t++){ memset(dp1,0,sizeof(dp1)); memset(dp2,0,sizeof(dp2)); scanf("%s%s%s",a,b,c); int lena = strlen(a), lenb = strlen(b), lenc = strlen(c); Lcs1(a,b,lena,lenb); Lcs2(a,b,lena,lenb); int ans = lenc; int left1[maxn],right1[maxn]; int lcnt1=0,rcnt1=0; int left2[maxn],right2[maxn]; int lcnt2=0,rcnt2=0; for(int i=0;i<lena;i++){ if(a[i] == c[0]){ int cnt = 1; for(int j=i+1;j<lena;j++){ if(a[j] == c[cnt]) cnt++; if(cnt == lenc){ left1[lcnt1++] = i; right1[rcnt1++] = j; break; } } } } for(int i=0;i<lenb;i++){ if(b[i] == c[0]){ int cnt = 1; for(int j=i+1;j<lenb;j++){ if(b[j] == c[cnt]) cnt++; if(cnt == lenc){ left2[lcnt2++] = i; right2[rcnt2++] = j; break; } } } } for(int i=0;i<lcnt1;i++) for(int j=0;j<lcnt2;j++){ ans = max(ans,dp1[left1[i]][left2[j]] + lenc + dp2[right1[i]][right2[j]] ); } printf("Case #%d: %d\n",t,ans); } }