HDU 6170 Two strings(dp)

来源:互联网 发布:数据挖掘原理 编辑:程序博客网 时间:2024/06/05 06:00

题目:点击打开链接

题意:给定两个字符串,假设为串a,串b。a由大写字母和小写字母组成,b由大写字母,小写字母,”.“,”*“ 组成。其中”.“可以代替任何的一个字母,”*“与其一个前缀如a*可代替a,aa,aaa...,以及空。(在这里注意的是a*可以是空 意味着*前面的一个字符和*可以一起去掉而不是只有*被去掉 比赛的时候题意理解错了QAQ) 最后判断a,b是否匹配。

思路:比赛时暴力看错题没过,但是据说暴力是能过的。看题解给的一般是dp。

dp[i][j]表示b[1..i]与a[1..j]匹配是否成功

初始值dp[0][0]=true,字符串从1开始

当前状态b[i]==a[j]或者b[i]=='.',dp[i][j]=dp[i-1][j-1];

当前状态b[i]=='*',

1.先讨论用*匹配1位或0位

1)a*->a:dp[i][j]=dp[i-1][j]

2)a*->空:dp[i][j]=dp[i-2][j]

2.假设已用*匹配多位

1)假定b[1..i-1]==a[1..j-1]已经匹配完成且a[j]==a[j-1],  则当前位可与a[j]位相匹配,dp[i][j]=true

2)假定b[1..i]==a[1..j-1]已经匹配完成且a[j]==a[j-1],  则当前位可与a[j]位相匹配,dp[i][j]=true

3.特别的

如果i==2且b[i]=='*',那么dp[i][0]=true,表示当串b为两位的串且第二位上是* ,那么它可以跟空串匹配

代码:

#include <bits/stdc++.h>using namespace std;const int maxn=2505;bool dp[maxn][maxn];int main(){    int T,lena,lenb;    char a[maxn],b[maxn];    scanf("%d",&T);    while(T--)    {        memset(dp,false,sizeof(dp));        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++)        {            if(i==2&&b[i]=='*')                dp[i][0]=true;            for(int j=1;j<=lena;j++)            {                if(a[j]==b[i]||b[i]=='.')                    dp[i][j]=dp[i-1][j-1];                if(b[i]=='*')                {                    dp[i][j]=dp[i-1][j]|dp[i-2][j];                    if((dp[i-1][j-1]||dp[i][j-1])&&a[j]==a[j-1])                        dp[i][j]=true;                }            }        }        if(dp[lenb][lena])            printf("yes\n");        else            printf("no\n");    }    return 0;}


原创粉丝点击