题意:输入两个A-Z组成的字符串,找到一个最短的串,使得两个串均是他的子串。
思路:最长公共序列问题。当i和j相等时,dp[i][j]=dp[i-1][j-1],不等时就是max(dp[i-1][j],dp[i][j-1]),如果当前的统计的数量大于s就置为s,否则加上s。
code:
#include <bits/stdc++.h>
using namespace std;#define cls(a,c) memset(a,c,sizeof (a))
#define ft(i,s,t) for (int i=s;i<=t;i++)
const int N=32,M=1005;char s1[N],s2[N];
int dp[N][N],num[N][N];
int s,cnt;
void sol(int i,int j){if (dp[i][j]==s) num[i][j]+=cnt;else if (dp[i][j]>s) dp[i][j]=s,num[i][j]=cnt;
}
int main()
{int T;scanf("%d",&T);getchar();ft(ca,1,T){cls (dp,63);cls(num,0);gets(s1+1);gets(s2+1);int len1=strlen(s1+1),len2=strlen(s2+1);dp[1][1]=0;num[1][1]=1;ft(i,1,len1+1) ft(j,1,len2+1){s=dp[i][j]+1,cnt=num[i][j];if (s1[i]==s2[j]) sol(i+1,j+1);else sol(i+1,j),sol(i,j+1);}printf("Case #%d: %d %d\n",ca,dp[len1+1][len2+1],num[len1+1][len2+1]);}
}