Two strings HDU

来源:互联网 发布:电子商务erp软件构造 编辑:程序博客网 时间:2024/05/29 07:11

和之前的一道cf很像,但明显难了很多;
麻瓜的我模仿之前那道一直在模拟,没想到还可以递推,亏我最近还在做什么递推练习TT;
题意:给出原串与匹配串,问能否匹配原串中所有的字符。’.’可以匹配所有字符,‘*’是给前一个字符附加一个buff,使其可以变成0~无穷个同样的字符;
思路:bool dp[i][j]代表str2前i个字符能否和str1前j个字符匹配(因为我们是用1去匹配2嘛,所以把2做i了)
所以先要搞一个大循环枚举str2,然后一个里面再套一个循环枚举str1;
如果str2[i]==’点’ 或者 str1[j]==str2[i];dp[i][j]=dp[i-1][j-1];
然后考虑str2[i]=‘星’;
1::dp[i][j]=max(dp[i-2][j],dp[i-1][j]);如果dp[i-2][j]=1;那_*可以换成空字符使dp[i][j]=1;如果dp[i-1][j]=1;那*可省去;如果都等于那随便取哪种情况,只要能匹配成功就行了;
2::如果str1[j]==str1[j-1]就代表*可取多个字符,所以要考虑dp[i-1][j-1]||dp[i][j-1]是否匹配成功;
最后是其他情况则代表匹配不成功;因为初始化是false,所以可以省略;
ps:如果str2【i】==’*’;则dp[2][0]=1;
因为任意字符搭配*可省略,顺带防止下面re;
咸鱼一只。。。不知道为什么每次比赛完看了官方题解就一下子有思路了;

#include <bits/stdc++.h>using namespace std;const int maxn=2555;char str1[maxn],str2[maxn];bool dp[maxn][maxn];int main(){    int T;    scanf("%d\n",&T);    while(T--)    {        memset(dp,false,sizeof(dp));        scanf("%s%s",str1+1,str2+1);        int l1=strlen(str1+1);        int l2=strlen(str2+1);        dp[0][0]=true;        for(int i=1; i<=l2; i++)        {            if(i==2&&str2[2]=='*')                dp[2][0] = true;            for(int j=1;j<=l1;j++)            {                if(str2[i]=='.'||str1[j]==str2[i])                    dp[i][j]=dp[i-1][j-1];                else if(str2[i]=='*')                {                    dp[i][j]=max(dp[i-2][j],dp[i-1][j]);                    if((dp[i-1][j-1]||dp[i][j-1])&&str1[j-1]==str1[j])                        dp[i][j] = true;                }            }        }        if(dp[l2][l1])            puts("yes");        else            puts("no");    }    return 0;}