HDU 6170 Two strings( DP+字符串匹配)

http://acm.hdu.edu.cn/showproblem.php?pid=6170

题目大意:

给出两个字符串s1和s2(长度小于等于2500)。

s1是一个正常的包含大小写字母的字符串,s2是一个类似正则表达式的字符串,除了大小写字母,还有 " . " 和 " * " 两种符号。

" . " 表示可以匹配任意一个字母。

" * ”表示前一个字符可以重复出现任意次(包括零)。

解题思路:

一道标准的dp O(n^2)。

用dp[i][j]来表示s2的前i个字符和s1的前j个字符能否匹配。

对于s2的每一个字符都跑一遍s1的全部字符dp,分别会遇到以下几种情况:

1.s2的该字符是 " * ",而且恰好是第二个字符,那么建立dp起点,也就是dp[i][0]=1;

2.s2的该字符是 " . ",那么说明s2的第j个字符匹配s1的第i个字符成立,dp[i][j]=dp[i-1][j-1];

3.s2的该字符是 " * ",而且不是第二个字符,那么首先考虑到的情况是 * 前一个字符出现0次的情况,所以至少有dp[i][j]=max(dp[i-2][j],dp[i-1][j]);

这种情况举例可以是 s1: abb   s2: abbc*   dp[i][j]=dp[i-2][j]

4.在第3个情况的前提,在 * 对应的前一个字符可能出现非零次时,如果 * 之前的字符都能全部匹配好: dp[i][j-1]==1 而且s1的第j个字符重复了: s1[j]==s1[j-1]的情况下,举例: s1: abbcccc   s2: abbc*

那么很显然只要判断 s2[i-1]==s1[j]成立 或者 s2[i-1]=='.' ,这两个满足任意一个都说明 " * "成功匹配到s1的第j个字符。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<bitset>
#include<functional>

using namespace std;

#define LL long long
const int INF = 0x3f3f3f3f;

int dp[2505][2505];
char s1[2505],s2[2505];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s%s",s1+1,s2+1);
        memset(dp,0,sizeof(dp));
        int len1=strlen(s1+1),len2=strlen(s2+1);
        dp[0][0]=1;
        for(int i=1;i<=len2;i++)
        {
            if(s2[i]=='*'&&i==2) dp[i][0]=1;
            for(int j=1;j<=len1;j++)
            {
                if(s2[i]=='.') dp[i][j]=dp[i-1][j-1];
                else if(s2[i]!='*')
                {
                    if(s2[i]==s1[j]) dp[i][j]=dp[i-1][j-1];
                }
                else
                {
                    dp[i][j]=max(dp[i-2][j],dp[i-1][j]);
                    if(dp[i][j-1]&&s1[j]==s1[j-1])
                    {
                        if(s2[i-1]==s1[j] || s2[i-1]=='.') dp[i][j]=1;
                    }
                }
            }
        }
        if(dp[len2][len1])
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;
    }
    return 0;
}
 
原文地址:https://www.cnblogs.com/YingZhixin/p/7589872.html