HDU 1501 Zipper dfs dp

Zipper
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 12854 Accepted Submission(s): 4619

Problem Description
Given three strings, you are to determine whether the third string can be formed by combining the characters in the first two strings. The first two strings can be mixed arbitrarily, but each must stay in its original order.

For example, consider forming “tcraete” from “cat” and “tree”:

String A: cat
String B: tree
String C: tcraete

As you can see, we can form the third string by alternating characters from the two strings. As a second example, consider forming “catrtee” from “cat” and “tree”:

String A: cat
String B: tree
String C: catrtee

Finally, notice that it is impossible to form “cttaree” from “cat” and “tree”.

Input
The first line of input contains a single positive integer from 1 through 1000. It represents the number of data sets to follow. The processing for each data set is identical. The data sets appear on the following lines, one data set per line.

For each data set, the line of input consists of three strings, separated by a single space. All strings are composed of upper and lower case letters only. The length of the third string is always the sum of the lengths of the first two strings. The first two strings will have lengths between 1 and 200 characters, inclusive.

Output
For each data set, print:

Data set n: yes

if the third string can be formed from the first two, or

Data set n: no

if it cannot. Of course n should be replaced by the data set number. See the sample output below for an example.

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

思路:
1.dfs记忆化搜索,考虑到每一种情况,然后用二维数组记录状态剪枝即可。
2.dp:对于匹配到i+j个字符,肯定是由dp[i][j-1]和dp[i-1][j]而来(i代表第一个串匹配了多少,j代表第二个串匹配了多少)。最终看终态即可。

代码:

#include<bits/stdc++.h>
using namespace std;
int v[220][220];
string str1,str2,str3;
int pos;
int dp[10][10];
void dfs(int s1,int s2,int s3)  //dfs方法
{
    if(pos) return ;
    if(v[s1][s2]==1) return ;
    if(s1==str1.length() && s2==str2.length())
    {
        pos = 1;
        return ;
    }
    if(str1[s1]!=str3[s3] && str2[s2]!=str3[s3])  return ;
    v[s1][s2]=1;
    if(str1[s1]==str3[s3]) dfs(s1+1,s2,s3+1);
    if(str2[s2]==str3[s3]) dfs(s1,s2+1,s3+1);
    return ;
}
int main()
{
   int t,n,Case = 1;
   scanf("%d",&t);
   while(t--)
   {
       memset(dp,0,sizeof(dp));
       cin>>str1>>str2>>str3;
    dp[0][0]=1;
    if(str1[0]==str3[0])
        dp[1][0]=1;
    if(str2[0]==str3[0])
        dp[0][1]=1;
    for(int i=0;i<=str1.length();i++)  //在这个代码里面,一定要从0开始,不能从1开始,不然所有状态没有遍历到。
    {
        for(int j=0;j<=str2.length();j++)
        {
            if(dp[i][j-1] && str2[j-1]==str3[i+j-1])
                dp[i][j]=1;
            if(dp[i-1][j] && str1[i-1]==str3[i+j-1])
                dp[i][j]=1;
        }
    }
       if(dp[str1.length()][str2.length()]) printf("Data set %d: yes\n",Case++);
       else printf("Data set %d: no\n",Case++);
   }
   return 0;
}

发布了22 篇原创文章 · 获赞 4 · 访问量 540

猜你喜欢

转载自blog.csdn.net/yp0413170331/article/details/101175666
今日推荐