https://vjudge.net/problem/UVA-10723
题意:
输入两个A~Z组成的字符串,找一个最短的串,使得输入的两个串均是它的子序列,另外还需要统计长度最短的串的个数。
思路:
求两个串的公共子序列。那么最短串就是len1+len2-LCS值。
d[i][j]表示串1取前 i 个字符,串2取前 j 个字符时的LCS。
状态转移方程如下:
如果A[i]=A[j],d[i][j]=d[i-1][j-1]+1。否则,d[i][j]=max( d[i-1][j] ,d[i][j-1] )。
1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 char s1[35], s2[35]; 8 int d[35][35], f[35][35]; 9 10 int main() 11 { 12 //freopen("D:\txt.txt", "r", stdin); 13 int T; 14 int kase = 0; 15 cin >> T; 16 getchar(); 17 while (T--) 18 { 19 gets(s1); 20 gets(s2); 21 int len1 = strlen(s1); 22 int len2 = strlen(s2); 23 memset(d, 0, sizeof(d)); 24 memset(f, 0, sizeof(f)); 25 for (int i = 0; i <= len1; i++) 26 f[i][0] = 1; 27 for (int i = 0; i <= len2; i++) 28 f[0][i] = 1; 29 for (int i = 1; i <= len1;i++) 30 for (int j = 1; j <= len2; j++) 31 { 32 if (s1[i - 1] == s2[j - 1]) 33 { 34 d[i][j] = d[i - 1][j - 1] + 1; 35 f[i][j] = f[i - 1][j - 1]; 36 } 37 else if (d[i - 1][j] > d[i][j - 1]) 38 { 39 d[i][j] = d[i - 1][j]; 40 f[i][j] = f[i - 1][j]; 41 } 42 else if (d[i - 1][j] < d[i][j - 1]) 43 { 44 d[i][j] = d[i][j - 1]; 45 f[i][j] = f[i][j - 1]; 46 } 47 else 48 { 49 d[i][j] = d[i - 1][j]; 50 f[i][j] = f[i - 1][j] + f[i][j - 1]; 51 } 52 } 53 printf("Case #%d: %d %lld ", ++kase, len1 + len2 - d[len1][len2], f[len1][len2]); 54 } 55 return 0; 56 }