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; }

你可能感兴趣的:(String)