zoukankan      html  css  js  c++  java
  • 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
    ");
    40         else printf("no
    ");
    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

  • 相关阅读:
    P4014 分配问题 网络流
    P4015 运输问题 网络流问题
    P4013 数字梯形问题 网络流
    网络流 P2770 航空路线问题
    网络流之最小费用最大流 P1251 餐巾计划问题
    二分图定理
    数论 C
    网络流 E
    网络流 之 P2766 最长不下降子序列问题
    scp使用
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5495094.html
Copyright © 2011-2022 走看看