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;
}
posted @ 2012-11-27 22:59  kedebug  阅读(416)  评论(0编辑  收藏  举报