题目大意:给出三个字符串,要求你用前两个字符串拼成第三个字符串,拼的规则是可以截取两个字符串的任意子串,然后再进行组装,问有多少种拼法
解题思路:参考了别人的思路,设置三个数组dp,dp1,dp2,这三个数组都是三维的。
dp[i][j][k]表示用第一串的前i个和第二串的前j个拼成了长度为k的字符串有多少种方法
dp1[i][j][k]表示用第一串的前i个和第二串的前j个拼成了长度为k的字符串有多少种方法,但最后一个字符是用第一个字符串的字符表示的
dp2的数组表示和dp1的相似,只不过最后一个字符是用第二串的字符表示的
这样一来的话,dp[i][j][k] = dp1[i][j][k] + dp2[i][j][k].
接着推dp1和dp2,因为两个相似,这里就只讲dp1
dp1[i][j][k] = dp[i-1][j][k]这是初始状态,接下来有两种情况
1. str1[i] == str3[k],那么dp1[i][j][k] += dp[i-1][j][k-1],这里用的是dp,为什么是dp,因为要用第一串的最后一个当第三串的第k个字符了,所以已经不在乎第k-1个是哪个字符串的了。
2.不等的情况,那么就保持原样就可以了
#include<cstdio>
#include<cstring>
#define mod 10007
#define maxn 70
int dp1[maxn][maxn][maxn], dp2[maxn][maxn][maxn], dp[maxn][maxn][maxn];
char str1[maxn], str2[maxn], str3[maxn];
void solve() {
int len1 = strlen(str1 + 1);
int len2 = strlen(str2 + 1);
int len3 = strlen(str3 + 1);
memset(dp,0,sizeof(dp));
memset(dp1,0,sizeof(dp1));
memset(dp2,0,sizeof(dp2));
for(int i = 0; i <= len1; i++)
for(int j = 0; j <= len2; j++)
dp[i][j][0] = dp1[i][j][0] = dp2[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) {
dp1[i][j][k] = dp1[i-1][j][k];
if(str1[i] == str3[k])
dp1[i][j][k] += dp[i-1][j][k-1];
dp1[i][j][k] %= mod;
}
if(j) {
dp2[i][j][k] = dp2[i][j-1][k];
if(str2[j] == str3[k])
dp2[i][j][k] += dp[i][j-1][k-1];
dp2[i][j][k] %= mod;
}
dp[i][j][k] = (dp1[i][j][k] + dp2[i][j][k] ) % mod;
}
printf("%d\n",dp[len1][len2][len3]);
}
int main() {
int test;
scanf("%d",&test);
while(test--) {
scanf("%s%s%s",str1+1,str2+1,str3+1);
solve();
}
return 0;
}