题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25839
思路:第一小问可以很快求出了,两个字符串的长度-LCS,然后第二问就要记忆化搜索了,dp[i][j][l]表示A串的前i个和B串的前j个组合,长度为l的组合数。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define MAXN 33 7 #define FILL(a,b) memset(a,b,sizeof(a)) 8 typedef long long ll; 9 10 int n,len,len1,len2,dp1[MAXN][MAXN]; 11 ll dp2[MAXN][MAXN][MAXN*2]; 12 13 char str1[MAXN],str2[MAXN]; 14 int LCS() 15 { 16 FILL(dp1,0); 17 for(int i=1;i<=len1;i++){ 18 for(int j=1;j<=len2;j++){ 19 if(str1[i-1]==str2[j-1])dp1[i][j]=dp1[i-1][j-1]+1; 20 else dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]); 21 } 22 } 23 return dp1[len1][len2]; 24 } 25 26 ll dfs(int l1,int l2,int l) 27 { 28 if(dp2[l1][l2][l]!=-1)return dp2[l1][l2][l]; 29 else if(l==len)return l1==len1&&l2==len2; 30 else if(l1==len1)return dp2[l1][l2][l]=dfs(l1,l2+1,l+1); 31 else if(l2==len2)return dp2[l1][l2][l]=dfs(l1+1,l2,l+1); 32 else if(str1[l1]==str2[l2])return dp2[l1][l2][l]=dfs(l1+1,l2+1,l+1); 33 return dp2[l1][l2][l]=dfs(l1+1,l2,l+1)+dfs(l1,l2+1,l+1); 34 } 35 36 37 int main() 38 { 39 int _case=1; 40 scanf("%d",&n); 41 while(n--){ 42 scanf("%s%s",str1,str2); 43 len1=strlen(str1),len2=strlen(str2); 44 len=len1+len2-LCS(); 45 FILL(dp2,-1); 46 printf("Case %d: %d %lld\n",_case++,len,dfs(0,0,0)); 47 } 48 return 0; 49 }