2017多校9 Two string hdu 6170 dp

来源:互联网 发布:淘宝搜索儿童服装秋装 编辑:程序博客网 时间:2024/06/05 16:07

题目链接
题目大意:给你两个字符串A B,A由大小写字母组成,B由大小写字符和 . 和 *组成现在问你AB能够匹配
其中 . 可以匹配任何字符 * 表示其前面一位的字符可以出现任意多次 可以为0次。


思路:首先来考虑dp[i][j]表示A串1-i用B串的1-j能否匹配
转移的时候就考虑B串 如果当前字符是 . 那么dp[i][j]=dp[i-1][j-1]
如果是普通字符 dp[i][j] = dp[i-1][j-1] && A[i] == B[j]
如果是 * 那么分几种情况考虑
考虑*重复0次 那么dp[i][j] = dp[i][j-2]
考虑重复1次 那么dp[i][j] = dp[i][j-1]
考虑重复多次 那么dp[i][j] = dp[i-1][j] && A[i]==A[i-1]

代码:

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<string>#include<set>#include<map>#include<queue>#include<stack>#include<cstring>#define clr(x) memset(x,0,sizeof(x))using namespace std;#define LL long longbool dp[2505][2505];int main(){    int t;    scanf("%d",&t);    while(t--)    {        clr(dp);        char s1[2505];        char s2[2505];        scanf("%s%s",s1,s2);        int len1 = strlen(s1);        int len2 = strlen(s2);        dp[0][0] = true;        for(int j = 1;j<len2;j++)        {            if(s2[j]=='*')            {                dp[0][j+1] = dp[0][j-1];            }        }        for(int i = 0;i<len1;i++)        {            for(int j = 0;j<len2;j++)            {                int ii = i+1; // 字符串和dp数组差一位 所以加1                int jj = j+1;                if(s2[j]=='.')                {                    dp[ii][jj] = dp[ii-1][jj-1];                }                else if(s2[j]=='*')                {                    dp[ii][jj] = (dp[ii][jj-2] || (dp[ii][jj-1]) ||  (dp[ii-1][jj] && s1[i]==s1[i-1]));                }                else                {                    dp[ii][jj] = (dp[ii-1][jj-1] && s1[i]==s2[j]);                }            }        }        printf("%s\n",dp[len1][len2]?"yes":"no");    }    return 0;}
原创粉丝点击