zzuli 2176 lcs

来源:互联网 发布:amds汽车材料数据系统 编辑:程序博客网 时间:2024/06/05 04:29

题目大意

给两个字符串 要求写出第三个字符串 要求 :
1,这两个字符串市第三个字符串的子序列
2,在满足1的条件下第三个字符串的长度最短 求满足1,2的方案数

思路

最长公共子序列变形
设dp[i][j] 表示1串前i个字符和2串前j个字符可以得到的满足题意的长度
sum[i][j] 表示方案数
那么s1[i]==s2[j]时 dp[i][j] = dp[i-1][j-1]+1,sum[i][j] = sum[i-1][j-1]
否则 dp[i][j] = min(dp[i-1][j],dp[i][j-1])+1
如果dp[i-1][j] == dp[i][j-1] , sum[i][j] = sum[i-1][j]+sum[i][j-1]
否则 如果dp[i][j-1] < dp[i-1][j] , sum[i][j] = sum[i][j-1]
如果dp[i][j-1] > dp[i-1][j] , sum[i][j] = sum[i-1][j]

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stack>#include<queue>#include<iostream>#include<vector>using namespace std;typedef long long LL;LL dp[45][45];LL sum[45][45];char s1[45];char s2[45];int main(){    int t;    scanf("%d",&t);    while (t--){        memset(dp,0,sizeof(dp));        memset(sum,0,sizeof(sum));        scanf("%s",s1+1);scanf("%s",s2+1);        int m = strlen(s1+1); int n = strlen(s2+1);        for (int i = 0;i <= m; ++i) dp[i][0] = i,sum[i][0] = 1;        for (int i = 0;i <= n; ++i) dp[0][i] = i,sum[0][i] = 1;        for (int i = 1;i <= m; ++i){            for (int j = 1;j <= n; ++j){                if (s1[i] == s2[j]){                    dp[i][j] = dp[i-1][j-1]+1;                    sum[i][j] = sum[i-1][j-1];                }else{                    dp[i][j] = min(dp[i-1][j],dp[i][j-1])+1;                    if (dp[i][j-1]>=dp[i-1][j]) sum[i][j] += sum[i-1][j];                    if (dp[i-1][j]>=dp[i][j-1]) sum[i][j] += sum[i][j-1];                }            }        }        printf("%lld %lld\n",dp[m][n],sum[m][n]);    }    return 0;}
原创粉丝点击