Loading

POJ 2192 :Zipper(DP)

Zipper
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 17585   Accepted: 6253

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
 
  DP一直以来都没怎么看,觉得很难,也只会抄抄模板和处理一些简单的背包。于是比赛出现了这道比较简单的题还是不会,要开始去学学DP了。

  题意:给出3个字符串,分别为A串和B串还有C串,题目保证A的长度+B的长度=C的长度,C里面包含着A和B的字符,然后判断A和B在C里面的字符顺序还是不是和原来的A和B保持原样。

  做法:建立一个DP数组dp[i][j],第一维i表示使用了A的前i个字符,第二维j表示使用了B的前j个字符,然后赋予1或者0判断是否可以组成。如果此时c[i+j]==a[i]&&dp[i-1][j]则表示可以使用a[i]这个字符来组成c[i+j],所以dp[i][j]=1。同理,如果c[i+j]==b[j]&&dp[i][j-1]则表示可以使用b[j]来组成c[i][j],所以dp[i][j]=1。(我这里直接让dp[i][j]的i和j都向后偏移了1)。状态转移方程:dp[i][j]=(c[i+j]==a[i]&&dp[i-1][j])||(c[i+j]==b[i]&&dp[i][j-1])。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <queue>
 6 #include <iostream>
 7 #include <vector>
 8 using namespace std;
 9 #define MAXN 1010
10 #define inf 1000000
11 typedef pair<int,int> P;
12 int dp[MAXN][MAXN];
13 
14 int main()
15 {
16     int t;
17     cin>>t;
18     string a,b,c;
19     for(int cas=1;cas<=t;cas++){
20         cin>>a>>b>>c;
21         memset(dp,0,sizeof(dp));
22         int la=a.size(),lb=b.size(),lc=c.size();
23         int i,j,k;
24         dp[0][0]=1;
25         for(i=0;i<=la;i++){
26             for(j=0;j<=lb;j++){
27                 if(i<la&&a[i]==c[i+j]&&dp[i][j]){
28                     dp[i+1][j]=1;
29                 }
30                 if(j<lb&&b[j]==c[i+j]&&dp[i][j]){
31                     dp[i][j+1]=1;
32                 }
33             }
34         }
35         bool flag=true;
36         if(!dp[la][lb]) flag=false;
37 
38         printf("Data set %d: ",cas);
39         if(flag) printf("yes\n");
40         else printf("no\n");
41     }
42 
43     return 0;
44 }
45 /*
46     如果串a的前i个字符和串b的前j个字符组成串c
47     并且满足未加入第i或j个字符前dp[i][j]可行
48     那么dp[i][j]=1
49 */

 

2016-05-15

 

posted @ 2016-05-15 13:24  Shadowdsp  阅读(312)  评论(0编辑  收藏  举报