http://acm.hdu.edu.cn/showproblem.php?pid=6170
给你两个串a串和b串,问b串能否变成a串。b串特殊的地方就是有一个能变成任意字符的’.’号和能使前一个字符出现任意(包括0)次的‘*’号。
比赛的时候一点都没往dp想过,觉得是用某种字符串算法,看了题解之后才明白。似乎自己构建一个自动机也是可过过得。
这一题的特殊之处就是对于’*’的处理,’.’可以看做是任意字符所以还好处理一些,但是星号还可以使字符消失。
#include<bits/stdc++.h>
using namespace std;
bool dp[2600][2600];
int main()
{
int T, len1, len2;
char str1[2600], str2[2600];
scanf("%d", &T);
while(T--)
{
scanf("%s%s", str1+1, str2+1);
len1=strlen(str1+1);
len2=strlen(str2+1);
memset(dp, 0, sizeof(dp));
dp[0][0]=true;
//i表示A串0-i个字符,j表示B串0-j个字符
for(int i=1; i<=len1; i++)
{
for(int j=1; j<=len2; j++)
{
//当B串是X*(X表示任意字符,但是题目说了X不会也是星号)的时候,可以由这两个字符构成长度为0的A串,就是消去的意思。
if(j==2&&str2[j]=='*')
dp[0][j]=true;
if(str1[i]==str2[j]||str2[j]=='.')
dp[i][j]=dp[i-1][j-1];
if(str2[j]=='*')
{
//dp[i][j-2]表示的消去前一个值,dp[i][j-1]表示前一个值出现1次
dp[i][j]=dp[i][j-2]|dp[i][j-1];
if(str1[i]==str1[i-1])
dp[i][j]=dp[i][j]|dp[i-1][j-1]|dp[i-1][j];
}
// printf("dp[%d][%d]=%d\n", i, j, dp[i][j]);
}
}
if(dp[len1][len2]==true)
printf("yes\n");
else
printf("no\n");
}
return 0;
}
这一场挺多dp题的,感觉除非是很明显的dp题,不然我都看不出来。多做点dp吧。。