HDU 6170 Two strings (dp)

/**
 * 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6170
 * 字符串match, ‘.’代表匹配任意一个字符,“*” 代表前面的那个字符可以重复
 * 出现0到无穷次。
 * 
 * 思路: dp[i][j];代表前i个字符与另一个前j个字符是否能匹配? true:false;
 * 假设i是B串,j是A串
 * 如果是:不是*,那就直接判断相等或者其中一个是否为点。是进行转移 dp[i][j]=dp[i-1][j-1];
 * 如果是*,我们需要从dp[i-1][j] dp[i-2] 转过来,
 * 如果 A串的当前字符与之前一样,那么还可以从 dp[i-1][j-1],dp[i][j-1]转过来。
 */

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2600;

char a[maxn], b[maxn];
bool dp[maxn][maxn];
int lena, lenb;
int main()
{
    int T;
    scanf("%d%*c", &T);
    while (T--)
    {
        memset(dp, 0, sizeof(dp));
        a[0] = b[0] = 1;
        scanf("%s%s",a+1,b+1);
        lena = strlen(a+1);
        lenb = strlen(b+1);
        dp[0][0] = true;
        for (int i = 1; i <= lenb; i++)
        {
            for (int j = 0; j <= lena; j++)
            {
                if (b[i] == '.' || a[j] == b[i])
                    dp[i][j] |= dp[i - 1][j - 1];
                else if (b[i] == '*')
                {
                    dp[i][j] |= dp[i - 2][j];
                    dp[i][j]|=dp[i - 1][j];
                    if (a[j - 1] == a[j])
                    {
                        dp[i][j]|=dp[i-1][j-1];
                        dp[i][j]|=dp[i][j-1];
                    }
                }
            }
        }
        puts(dp[lenb][lena] ? "yes" : "no");
    }
    return 0;
}
posted @ 2017-08-23 10:56  Code-dream  阅读(77)  评论(0编辑  收藏  举报