• HDU 1501 Zipper


    问前两个字符串是否能组合成第三个字符串,保持原字符串的顺序。

    看到别人的代码有两种做法:

    1、DFS

    hash数组标记足迹,可以减少重复搜索的次数。

    这个代码太过巧妙,体会体会再体会。。

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 bool hash[205][205];
     8 char s1[205], s2[205], s3[410];
     9 
    10 bool DFS(int a, int b, int c)
    11 {
    12     if(s3[c] == '')
    13         return true;
    14     if(hash[a][b])
    15         return false;
    16     hash[a][b] = true;
    17     if(s1[a] == s3[c] && DFS(a+1, b, c+1))
    18         return true;
    19     if(s2[b] == s3[c] && DFS(a, b+1, c+1))
    20         return true;
    21     return false;
    22 }
    23 
    24 int main(void)
    25 {
    26     #ifdef LOCAL
    27         freopen("1501in.txt", "r", stdin);
    28     #endif
    29 
    30     int T, kase;
    31     scanf("%d", &T);
    32     for(kase = 1; kase <= T; ++kase)
    33     {
    34         printf("Data set %d: ", kase);
    35         cin >> s1 >> s2 >> s3;
    36         memset(hash, false, sizeof(hash));
    37         if(DFS(0, 0, 0))
    38             printf("yes
    ");
    39         else
    40             printf("no
    ");
    41 
    42     }
    43     return 0;
    44 }
    代码君

    2、DP

    最优子结构分析:如上例,如果A、B可以组成C,那么,C最后一个字母e,必定是 A 或 C 的最后一个字母组成。

    C去除除最后一位,就变成是否可以求出 A-1和B 或者 A与B-1 与 是否可以构成 C-1
     
    状态转移方程:

    用dp[i][j] 表示 表示A前 i 为 和B 前j 位是否可以组成 C的前i+j位        

            dp[i][j]= (dp[i-1][j]&&(a[i]==c[i+j]))||(dp[i][j-1]&&(b[j]==c[i+j]))

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 bool dp[205][205];
     8 char s1[205], s2[205], s3[410];
     9 
    10 int main(void)
    11 {
    12     #ifdef LOCAL
    13         freopen("1501in.txt", "r", stdin);
    14     #endif
    15 
    16     int T, kase;
    17     scanf("%d", &T);
    18     for(kase = 1; kase <= T; ++kase)
    19     {
    20         printf("Data set %d: ", kase);
    21         cin >> (s1+1) >> (s2+1) >> (s3+1);
    22         int len1, len2, len3;
    23         len1 = strlen(s1+1);
    24         len2 = strlen(s2+1);
    25         len3 = strlen(s3+1);
    26         if(len1 + len2 != len3)
    27         {
    28             printf("no
    ");
    29             continue;
    30         }
    31         memset(dp, false, sizeof(dp));
    32         int i, j;
    33         i = 0;
    34         while(s1[i] == s3[i])    //处理边界
    35             dp[i++][0] = true;
    36         i = 0;
    37         while(s2[i] == s3[i])
    38             dp[0][i++] = true;
    39         for(i = 1; i <= len1; ++i)
    40             for(j = 1; j <= len2; ++j)
    41                 dp[i][j] = ((dp[i-1][j] && s1[i] == s3[i+j])
    42                             || (dp[i][j-1] && s2[j] == s3[i+j]));
    43 
    44 
    45         if(dp[len1][len2])
    46             printf("yes
    ");
    47         else
    48             printf("no
    ");
    49     }
    50     return 0;
    51 }
    代码君
  • 相关阅读:
    cocos2dx 解释二具体的启动过程:内存管理和回调
    允许Android随着屏幕转动的控制自由转移到任何地方(附demo)
    freemarker 空白处理
    采用Duplicate target database在线恢复秩序oracle datagard图书馆设备
    activiti入门2流程引擎API和服务基础设施
    【android】ImageView的src和background以及两者之间的神奇的差异
    HDU ACM 1007 Quoit Design 分而治之的方法,最近点
    Dynamics CRM2013/2015 禁止欢迎屏幕(Disable the Welcome Screen)
    2013年第42周二明智行动的艺术
    2013第42周一睡前
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3881585.html
Copyright © 2020-2023  润新知