uva 10723 Cyborg Genes(LCS变形)

题目:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=107450#problem/C

题意:输入两个字符串,找一个最短的串,使得输入的两个串均是他的子序列,统计长度最短的串的个数;

分析:最短串的长度就等于a串长度 + b串长度 - LCS( a, b )

借鉴于

c[i][j]表示a串前i个元素和b串前j个元素所能得到的方案数。l[i][j]表示LCS的长度

若a[i]=b[j],那么c[i][j]=c[i-1][j-1],即a串前i-1个元素和b串前j-1个元素得到的组合串的末尾加上一个相同的元素a[i],那么得到的新的组合串的个数还是和之前的组合串的个数一样

若a[i]!=b[j],  l[i][j]=max { l[i-1][j] , l[i][j-1]}

若l[i-1][j]>l[i][j-1],那说明从l[i-1][j]这种状态开始构建才能得到最终的LCS同时最终的组合串才不能漏掉共有的元素,所以c[i][i]=c[i-1][j],即在a串i-1个元素和b串j个元素组成的组合串的后面加上a[i],那么得到的新的组合串的个数和之前的组合串的个数是相同的

若l[i][j-1]>l[i-1][j],道理和上面是一样的,所以c[i][j]=c[i][j-1],相当于在之前的组合串后面加上元素b[j],得到新的组合串的个数不变

若l[i][j-1]=l[i-1][j],说明从两种状态都是能得到最终的LCS并且最终的组合串不会漏掉任何相同的公共元素,所以c[i][j]=c[i-1][j]+c[i][j-1] , 即用a串的i-1个元素和b串的j个元素组成的组合串的最后加上a[i]得到新的组合串和之前的组合串个数相同,另外用a串的i个元素和b串的的j-1个元素组成的组合串的最后加上b[j]得到新的组合串和之前的组合串个数相同,那么就是两者之和

 #include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int Max = ;
char a[Max],b[Max];
int c[Max][Max],l[Max][Max],B[Max][Max];
/*
void print(int i, int j)
{
if(i == 0 && j == 0)
return;
if(i == 0)
{
for(int k = 1; k <= j; k++)
printf("%c", b[k]);
return;
}
if (j == 0)
{
for(int k = 1; k <= i; k++)
printf("%c", a[k]);
return;
}
if(B[i][j] == 0)
{
print(i - 1, j - 1);
printf("%c", a[i]);
}
else if(B[i][j] == 1)
{
print(i - 1, j);
printf("%c", a[i]);
}
else
{
print(i, j - 1);
printf("%c", b[j]);
}
}
*/
int main()
{
int test;
scanf("%d", &test);
getchar();
for(int t = ; t <= test; t++)
{
gets(a + );
gets(b + );
int lena = strlen(a + );
int lenb = strlen(b + );
for(int i = ; i <= lena; i++)
{
for(int j = ; j <= lenb; j++)
c[i][j] = ;
}
memset(l, , sizeof(l));
memset(B, , sizeof(b));
for(int i = ; i <= lena; i++)
{
for(int j = ; j <= lenb; j++)
{
if(a[i] == b[j])
{
l[i][j] = l[i - ][j - ] + ;
c[i][j] = c[i - ][j - ];
B[i][j] = ;
}
else
{
l[i][j] = max(l[i - ][j], l[i][j - ]);
if(l[i - ][j] > l[i][j - ])
{
c[i][j] = c[i - ][j];
B[i][j] = ;
}
else if(l[i - ][j] < l[i][j - ])
{
c[i][j] = c[i][j - ];
B[i][j] = -;
}
else
{
c[i][j] = c[i - ][j] + c[i][j - ];
}
}
}
}
printf("Case #%d: %d %d\n", t, lena + lenb - l[lena][lenb], c[lena][lenb]); }
return ;
}
上一篇:Wordpress主题编辑器漏洞复现


下一篇:undefined