HDU6170 Two strings(dp,2017 HDU多校联赛 第9场)

来源:互联网 发布:别克车钥匙淘宝图片 编辑:程序博客网 时间:2024/06/05 00:32

Description

Giving two strings and you should judge if they are matched. The first
string contains lowercase letters and uppercase letters. The second
string contains lowercase letters, uppercase letters, and special
symbols: “.” and “”. . can match any letter, and means the front
character can appear any times. For example, “a.b” can match “acb” or
“abb”, “a*” can match “a”, “aa” and even empty string. ( “*” will not
appear in the front of the string, and there will not be two
consecutive “*”.

Input

The first line contains an integer T implying the number of test
cases. (T≤15) For each test case, there are two lines implying the two
strings (The length of the two strings is less than 2500).

Output

For each test case, print “yes” if the two strings are matched,
otherwise print “no”.

Sample Input

3aaa*abba.*abbaab

Sample Output

yesyesno

思路

题目跟正则表达式类似,给了一个原串,给了一个匹配串,问匹配串可不可以匹配原串.在题目中给的匹配字符有两个:

  • ‘.’可以匹配任意字符
  • ‘*’可以匹配它之前的一个字符任意次(可以为0)

设有两个串,分别是a和b串,分别代表原串和匹配串,令dp[i][j]代表b串中[1~i]和a串中[1~j]的字符是否匹配,则有以下状态转移关系:
1. 当b[i]==.或者 b[i]==a[j]时,此时dp[i][j]=dp[i1][j1]
2. 当b[i]==时,则匹配一个或者不匹配都合法,那么就由dp[i2][j]dp[i1][j]转移而来,因为可以匹配任意数量的字符,所以还要判断假如 a[j1]b[i1] 已成功匹配,并且a[j1]==a[j],显然当前的 * 可以继续匹配这一个字符,因此 dp[i][j]=true ,假如 a[j1]b[i] 已成功匹配(当前 * 已成功匹配若干位),且 a[j1]==a[j] ,则可以继续匹配这一个字符,因此dp[i][j]=true

代码

#include <cstdio>#include <cstring>#include <cctype>#include <string>#include <set>#include <iostream>#include <stack>#include <cmath>#include <queue>#include <vector>#include <algorithm>#define mem(a,b) memset(a,b,sizeof(a))#define inf 0x3f3f3f3f#define mod 1000007#define ll long longusing namespace std;const int N=2500+10;char a[N],b[N];bool dp[N][N];int main(){    int t;    scanf("%d",&t);    getchar();    while(t--)    {        mem(dp,0);        a[0]=b[0]='0';        gets(a+1);        gets(b+1);        int lena=strlen(a)-1;        int lenb=strlen(b)-1;        dp[0][0]=true;        for(int i=1;i<=lenb;i++)        {            if(i==2&&b[i]=='*')                dp[2][0]=true;            for(int j=1;j<=lena;j++)            {                if(b[i]=='.'||b[i]==a[j])                    dp[i][j]=dp[i-1][j-1];                else if(b[i]=='*')                {                    dp[i][j]=dp[i-2][j]|dp[i-1][j];                    if((dp[i-1][j-1]||dp[i][j-1])&&a[j-1]==a[j])//匹配连续的*                        dp[i][j]=true;                }            }        }        if(dp[lenb][lena])puts("yes");        else puts("no");    }  return 0;}
原创粉丝点击