题意:
给你三个字符串,求第一串的子串 + 第二串的子串 = 第三串的方法有几种
思路:
就是最长公共子序列,f[i][j][k]就代表第一串的前i个,第二串的前j个,构成第三串前k个的方法数;
如果第一串的第i个和第三串的第k个是一样的.
那么f[i][j][k] += f[i-1][j][k];
但是这样有一个问题,就是如果第一串第i个,第二串第j个,第三第三串第k个三个都一样怎么办,只有一个数组不能解决保存两个值,然后都加上去;
所以我们用三个数组f1,f2,f;
分别用于存第一串和第三串比较的值,还有第二串和第三串比较的值;
相加就是总值:
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 65;
const int M = 10007;
int f1[N][N][N];
int f2[N][N][N];
int f[N][N][N];
char str1[N] , str2[N],str3[N];
int len1 , len2 , len3;
int main() {
int t;
scanf("%d",&t);
while(t--) {
memset(f , 0 , sizeof(f));
scanf("%s%s%s",str1 + 1 ,str2 + 1 ,str3 + 1);
len1 = strlen(str1 + 1);
len2 = strlen(str2 + 1);
len3 = strlen(str3 + 1);
for(int i = 0 ; i <= len1 ; i++) {
for(int j = 0 ; j <= len2 ; j++) {
f[i][j][0] = f1[i][j][0] = f2[i][j][0] = 1;
}
}
for(int k = 1 ; k <= len3 ; k++) {
for(int i = 0 ; i <= len1 ; i++) {
for(int j = 0 ; j <= len2 ; j++) {
if(i) {
f1[i][j][k] = f1[i - 1][j][k];
if(str1[i] == str3[k]) {
f1[i][j][k] += f[i - 1][j][k - 1];
f1[i][j][k] %= M;
}
}
if(j) {
f2[i][j][k] = f2[i][j - 1][k];
if(str2[j] == str3[k]) {
f2[i][j][k] += f[i][j - 1][k - 1];
f2[i][j][k] %= M;
}
}
f[i][j][k] = f1[i][j][k] + f2[i][j][k];
f[i][j][k] %= M;
}
}
}
printf("%d\n",f[len1][len2][len3]);
}
}