UVa 11081 Strings(字符串匹配DP)
题意:
给定3个字符串,求前2个字符串的子串组成第三个字符串的情况的个数。
思路:
题目的思路似曾相识,无非就是源串和目标串的匹配。
利用数学归纳法的思想,就是第i个字符串参与或者不参与匹配。顺着这个思路问题迎刃而解。
一开始我只用到了一个dp数组,但是无奈怎么都是WA,看到网上有更简单的代码,其实思路都是一致的。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <algorithm>
using namespace std;
const int MAXN = 70;
int d1[MAXN][MAXN][MAXN], d2[MAXN][MAXN][MAXN], d[MAXN][MAXN][MAXN];
char b1[MAXN], b2[MAXN], b3[MAXN];
int solve()
{
int len1 = strlen(b1 + 1);
int len2 = strlen(b2 + 1);
int len3 = strlen(b3 + 1);
memset(d, 0, sizeof(d));
memset(d1, 0, sizeof(d1));
memset(d2, 0, sizeof(d2));
for (int i = 0; i <= len1; ++i)
for (int j = 0; j <= len2; ++j)
d[i][j][0] = d1[i][j][0] = d2[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) {
d1[i][j][k] = d1[i-1][j][k];
if (b1[i] == b3[k])
d1[i][j][k] += d[i-1][j][k-1];
d1[i][j][k] %= 10007;
}
if (j) {
d2[i][j][k] = d2[i][j-1][k];
if (b2[j] == b3[k])
d2[i][j][k] += d[i][j-1][k-1];
d2[i][j][k] %= 10007;
}
d[i][j][k] = (d1[i][j][k] + d2[i][j][k]) % 10007;
}
return d[len1][len2][len3];
}
int main()
{
int cases;
scanf("%d", &cases);
while (cases--)
{
scanf("%s %s %s", b1+1, b2+1, b3+1);
printf("%d\n", solve());
}
return 0;
}
-------------------------------------------------------
kedebug
Department of Computer Science and Engineering,
Shanghai Jiao Tong University
E-mail: kedebug0@gmail.com
GitHub: http://github.com/kedebug
-------------------------------------------------------