loj 1013(LCS+记忆化搜索)

题目链接: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 }
View Code

 

你可能感兴趣的:(搜索)