Cyborg Genes
题意:给你两个字符串,求一个最短的串,使得这两个串是目标串的子串。要求输出符合要求的最短串长度和个数。
Sample Input
3
ABAAXGF
AABXFGA
ABA
BXA
AABBA
BBABAA
Sample Output
Case #1: 10 9
Case #2: 4 1
Case #3: 8 10
状态
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]串a的前i个字符和串b的前j个字符的最大匹配数,初始条件:
d
p
[
0
]
[
i
]
=
0
dp[0][i]=0
dp[0][i]=0;
d
p
[
i
]
[
0
]
=
0
dp[i][0]=0
dp[i][0]=0;
转移方程:
if(a[i]==b[j]){
dp[i][j]=dp[i-1][j-1];
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1];
}
为了求出符合要求的最短串个数
n
u
m
[
i
]
[
j
]
num[i][j]
num[i][j]:
目标串的数量就是所有长度相同的情况的数量加和(路径的加和);
if(a[i]==b[j]) {
num[i][j]=num[i-1][j-1];
} else if(dp[i-1][j]<dp[i][j-1]) {
num[i][j]=num[i][j-1];
} else if(dp[i-1][j]>dp[i][j-1]) {
num[i][j]=num[i-1][j];
} else {
num[i][j]=num[i-1][j]+num[i][j-1];
}
有可能有空串,用gets读数据.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char a[40];
char b[40];
long long dp[40][40];
long long num[40][40];
int main() {
int t,na,nb,ans;
cin>>t;
getchar();
int cas=0;
while(t--) {
cas++;
gets(a+1);
gets(b+1);
na=strlen(a+1);
nb=strlen(b+1);
dp[0][0]=0;
num[0][0]=1;
for(int i=1; i<=na; i++) {
dp[i][0]=0;
num[i][0]=1;
}
for(int i=1; i<=na; i++) {
dp[0][i]=0;
num[0][i]=1;
}
for(int i=1; i<=na; i++) {
for(int j=1; j<=nb; j++) {
if(a[i]==b[j]) {
dp[i][j]=dp[i-1][j-1]+1;
num[i][j]=num[i-1][j-1];
} else if(dp[i-1][j]<dp[i][j-1]) {
dp[i][j]=dp[i][j-1];
num[i][j]=num[i][j-1];
} else if(dp[i-1][j]>dp[i][j-1]) {
dp[i][j]=dp[i-1][j];
num[i][j]=num[i-1][j];
} else {
dp[i][j]=dp[i-1][j];
num[i][j]=num[i-1][j]+num[i][j-1];
}
}
}
ans=dp[na][nb];
//cout<<ans<<endl;
cout<<"Case #"<<cas<<": "<<na+nb-ans<<" "<<num[na][nb]<<endl;
}
return 0;
}