HDU

来源:互联网 发布:知乎周刊在哪里看 编辑:程序博客网 时间:2024/06/11 05:44

题目描述:

点击打开链接

题意给你两串字符串,其中'.'可以替换成任意字符,'*'表示前面一个字符可以出现任意次。

用dp来处理,用dp[i][j]来表a[i],b[j]是否匹配,这题有一个及其神奇的操作就是a*可以处理成空串,*居然可以表示出现0次,真的是无比佩服出题人的脑洞,剩下就是状态转移,其实都很简单,只要细心就行,如果b[j]==a[i]或者b[j]=='.'那么该点肯定可以匹配dp[i][j]=dp[i-1][j-1],如果b[j]=='*'那么讨论这个*的情况,第一处理成空串dp[i][j]=dp[i-2][j],第二不管这个*号,dp[i][j]=dp[i-1][j],然后考虑这个*号如果a[i]==a[i-1]的话,dp[i][j]=dp[i-1][j]||dp[i-1][j-1]。

AC代码:

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<cmath>#include<stack>#include<vector>#include<set>#include<queue>#include<algorithm>using namespace std;const int MAXM=2505;bool dp[MAXM][MAXM];char s1[MAXM],s2[MAXM];int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%s",s1+1);        scanf("%s",s2+1);        memset(dp,false,sizeof(dp));        dp[0][0]=true;        if (s2[2]=='*')            dp[0][2]=true;        int lena=strlen(s1+1);        int lenb=strlen(s2+1);        for (int i=1;i<=lena;i++)        {            for (int j=1;j<=lenb;j++)            {                if (s1[i]==s2[j])                    dp[i][j]=dp[i-1][j-1];                if (s2[j]=='.')                    dp[i][j]=dp[i-1][j-1];                if (s2[j]=='*')                {                    dp[i][j]=dp[i][j-2]|dp[i][j-1];                    if (s1[i]==s1[i-1])                        dp[i][j]=dp[i-1][j]|dp[i-1][j-1];                }            }        }        if (dp[lena][lenb]) printf("yes\n");        else printf("no\n");    }    return 0;}




原创粉丝点击