您的位置:首页 > 其它

HDU 1501 Zipper(dp)

2017-07-25 00:01 351 查看
Description

给出两个较短的串a和b和一个串长为a和b串长之和的串c,问a和b是否可以组成c

Input

第一行一整数T表示用例组数,每组用例输入三个串a,b,c,a和b串长不超过200,用例组数不超过1000

Output

如果a和b可以组成c则输出yes,否则输出no

Sample Input

3

cat tree tcraete

cat tree catrtee

cat tree cttaree

Sample Output

Data set 1: yes

Data set 2: yes

Data set 3: no

Solution

dp[i][j]表示a的第i个字符之后和b的前j个字符之后是否可以和c的后半部分匹配,令k=i+j,则有转移方程dp[i][j]=(a[i]==c[k]&&dp[i+1][j])||(b[j]==c[k]&&dp[i][j+1])

防止同一种状态被计算多次记忆化一下即可

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 444
char a[maxn],b[maxn],c[maxn];
int dp[maxn][maxn];
//dp[i][j]表示第一个串的前i位和第二个串的前j位是否可以组成第三个串的前i+j位
int dfs(int i,int j,int k)
{
if(~dp[i][j])return dp[i][j];
if(c[k]=='\0')return 1;
dp[i][j]=0;
if(a[i]==c[k])dp[i][j]|=dfs(i+1,j,k+1);
if(b[j]==c[k])dp[i][j]|=dfs(i,j+1,k+1);
return dp[i][j];
}
int main()
{
int T,res=1;
scanf("%d",&T);
while(T--)
{
scanf("%s%s%s",a,b,c);
memset(dp,-1,sizeof(dp));
printf("Data set %d: %s\n",res++,dfs(0,0,0)?"yes":"no");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: