• HDU 5707 Combine String(动态规划)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5707

    题意:

    给你三个字符串 S1, S2, S3, 让你判断 S3 是否恰好由字符串 S1 和 S2组成, S1 为 S3 的子串, S2 也为 S3 的子串, 可以不连续.

    思路:

    设 dp[i][j] 表示字符串 S3 的前 i + j 位是否可以由字符串 S1 的前 i 位以及字符串 S2 的前 j 位组成. dp[i][j] = 1 表示可以, dp[i][j] = 0 则表示不可以.

      则 dp[i][j] 可以由 dp[i - 1][j] 和 dp[i][j - 1] 转移过来.如果 dp[i][j] 由 dp[i - 1][j] 转移而来,那么应该满足:

        dp[i - 1][j] 是合法状态( 即 dp[i - 1][j] = 1 ) 且 S1的第 i 个字符必须等于 S3 的第 i + j 个字符.

      如果 dp[i][j] 由 dp[i][j - 1] 转移而来, 那么应该满足:

        dp[i][j - 1] 是合法状态( 即 dp[i][j - 1] = 1 ) 且 S2 的第 j 个字符必须等于 S3 的第 i + j 个字符.

    综上就可以得到状态转移方程:

        i == 0 && j == 0 : dp[i][j] = 1;                   //显然空串可以由两个空串组成,是合法状态. 除此之外其他状态的初始化应该为 0

        i != 0  && j == 0 : dp[i][j] = dp[i - 1][j] && S1[i - 1] == S3[i + j - 1]     //字符串下标从零开始 

        i == 0 && j != 0  : dp[i][j] = dp[i][j - 1] && S2[j - 1] == S3[i + j - 1]

        i != 0  && j != 0  : dp[i][j] = ( dp[i - 1][j] && S1[i - 1] == S3[i + j - 1] )  ||  ( dp[i][j] = dp[i][j - 1] && S2[j - 1] == S3[i + j - 1] ) //两者满足其一即可

    除此之外, 题目中还要求 S3 必须恰好由 S1 和 S2 组成, 则除满足 dp[ len(S1) ][ len(S2) ] == 1 之外, len(S1) + len(S2) == len(S3) 也应必须成立.

    代码:

     1 #include <iostream>
     2 #include <cstring>
     3 
     4 using namespace std;
     5 typedef long long LL;
     6 const int MAXN = 2000;
     7 int dp[MAXN + 3][MAXN + 3];
     8 
     9 int main() {
    10     ios_base::sync_with_stdio(0); cin.tie(0);
    11     string s1, s2, s3;
    12     while(cin >> s1 >> s2 >> s3) {
    13         dp[0][0] = 1; //dp[0][0] 为合法状态
    14         unsigned int i, j;
    15         for(i = 0; i <= s1.length(); i++) {
    16             for(j = 0; j <= s2.length(); j++) {
    17                 if(i && j) dp[i][j] = 0; //除 dp[0][0] 之外 其他状态的初始化
    18                 if(i) dp[i][j] = dp[i - 1][j] & (s1[i - 1] == s3[i + j - 1]); //由于非0即1,所以可以按位与
    19                 if(j) dp[i][j] |=dp[i][j - 1] & (s2[j - 1] == s3[i + j - 1]);  // “ |= ”  是因为 俩个转移状态满足其一就可
    20             }
    21         }
    22         cout << ( (dp[i - 1][j - 1] && i + j - 2 == s3.length() ) ? "Yes":"No") << endl;
    23     }
    24     return 0;
    25 }
  • 相关阅读:
    [Swift通天遁地]五、高级扩展-(2)扩展集合类型
    [Swift通天遁地]五、高级扩展-(1)快速检测设备属性:版本、类型、屏幕尺寸
    [Swift]LeetCode266.回文全排列 $ Palindrome Permutation
    [Swift]LeetCode265.粉刷房子 II $ Paint House II
    [Swift]LeetCode264.丑数 II | Ugly Number II
    [Swift通天遁地]四、网络和线程-(15)程序内购功能
    [Swift通天遁地]四、网络和线程-(14)创建一个Socket服务端
    hdu 4888 Redraw Beautiful Drawings(最大流,判环)
    【剑指offer】斐波那契序列与跳台阶
    Asp.NET之对象学习
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5877070.html
Copyright © 2020-2023  润新知