题目:
思路:
求两个串的最长公共子序列,则这个最短的串就是给出的两个串的长度和减去最长公共子序列的长度。
状态转移方程:
如果s[i-1]==t[j-1]就有dp[i][j] = dp[i-1][j-1]+1;
否则有dp[i][j] = max(dp[i-1][j], dp[i][j-1])
dp[i][j]表示从s中选前i个,从t中选前j个字符中最长公共子序列的长度。
注意:
给出的两个串可能是空串,这时候就要用gets来输入字符串。
代码:
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define mod 1000000007 #define FRE() freopen("in.txt","r",stdin) #define FRO() freopen("out.txt","w",stdout) using namespace std; typedef long long ll; typedef pair<int,ll> pii; const int maxn = 50; int dp[maxn][maxn],n[maxn][maxn]; char s[maxn],t[maxn]; int main(){ //FRE(); int T,kase = 0; scanf("%d",&T); getchar(); while(T--){ gets(s); gets(t); //scanf("%s%s",s,t); int lens = strlen(s); int lent = strlen(t); memset(dp,0,sizeof(dp)); memset(n,0,sizeof(n)); for(int i=0; i<maxn; i++){ n[0][i] = 1; n[i][0] = 1; } for(int i=1; i<=lens; i++){ for(int j=1; j<=lent; j++){ if(s[i-1]==t[j-1]){ dp[i][j] = dp[i-1][j-1]+1; n[i][j] = n[i-1][j-1]; }else if(dp[i-1][j]==dp[i][j-1]){ dp[i][j] = dp[i-1][j]; n[i][j] = n[i-1][j]+n[i][j-1]; }else{ dp[i][j] = max(dp[i-1][j],dp[i][j-1]); if(dp[i-1][j]>dp[i][j-1]){ n[i][j] = n[i-1][j]; } else{ n[i][j] = n[i][j-1]; } } } } printf("Case #%d: %d %d\n",++kase,lens+lent-dp[lens][lent],n[lens][lent]); } return 0; }