您的位置:首页 > 其它

HDU 6170 Two strings(dp)

2017-08-27 17:14 429 查看
http://acm.hdu.edu.cn/showproblem.php?pid=6170

题意:
给出两个字符串,第二个字符串中会有两个特殊字符$.$和$*$,$.$可以匹配任一字符,$*$可以使前面一个字符出现任意次,注意,可以出现0次,也就是把前面那个删了。问这两个串是否可以匹配。

思路:

一开始以为是模拟。。。囧。

$dp[i][j]$表示第二个字符串的前i个和第一个字符串的前j个是否可以匹配。一开始$dp[0][0]=0$。

情况分为以下几种:

如果 $s2[i] == . 或者s2[i] == s1[j]$时,$dp[i][j]$ 的状态取决于状态$dp[i-1][j-1]$。

如果$s2[i] == ‘*‘$时,$dp[i][j] == dp[i-1][j] | dp[i-2][j]$,因为可以让前面的字符出现1次或者0次。并且当$(dp[i-1][j-1] || dp[i][j-1]) $ && $s1[j-1] == s1[j]$ 时,$dp[i][j]$必定为true。可以仔细想一想。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn=2500+5;

char s1[maxn],s2[maxn];
int dp[maxn][maxn];

int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s1+1,s2+1);
int len1=strlen(s1+1),len2=strlen(s2+1);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=len2;i++)
{
if(i==2 && s2[i]=='*')  dp[i][0]=1;
for(int j=1;j<=len1;j++)
{
if(s2[i]==s1[j] || s2[i]=='.')  dp[i][j]=dp[i-1][j-1];
else if(s2[i]=='*')
{
dp[i][j]=dp[i-1][j]||dp[i-2][j];
if((dp[i-1][j-1]||dp[i][j-1])&& s1[j-1]==s1[j])  dp[i][j]=1;
}
}
}
if(dp[len2][len1])  puts("yes");
else puts("no");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: