HDU 5707 Combine String 动态规划

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5707
题目解析:
按题意,三个字符串 a,b,c 求c是否能由a,b按顺序构成
定义数组 dp[2000][2000],
dp[i][j] 代表用字符串a的前i位和字符串b的前j位,可以组成字符串c的前i+j位
则递推公式(状态转换公式):

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

递推公式的含义是:如果 a 的前 i 位和 b 的前 j 位能构成 c 的前 i+j 位的话,则只有两种可能:
1、 a[i-1] == c[i+j-1] 即a的第i个字符等于c的第i+j个字符
并且 dp[i-1][j] == true 即 a 的前 i-1 个字符和 b 的前 j 位字符能构成 c 的前 i+j-1 位
2、 b[j-1] == c[i+j-1] 即b的第j个字符等于c的第i+j个字符
并且 dp[i][j-1] == true 即 a 的前 i 个字符和 b 的前 j-1 个字符能构成 c 的前 i+j-1 位

程序从初始化 dp[0][0]=true 开始递推

#include <algorithm>
#include <iostream>

using namespace std;
char a[2000], b[2000], c[2000];
bool dp[2001][2001];

int main() {
    int i, j, aL, bL, cL;
    while (cin >> a >> b >> c) {
        memset(dp, 0, sizeof(dp));
        aL = strlen(a);
        bL = strlen(b);
        cL = strlen(c);
        if (aL + bL != cL) {
            cout << "No" << endl;
            continue;
        }
        for (i = 0; i <= aL; i++)
            for (j = 0; j <= bL; j++) {
                if (i == 0 && j == 0) {
                    dp[i][j] =
                        true;  // dp[0][0] a的前0个和b的前0个一定组成C的前0ge
                }
                if (i > 0) {
                    dp[i][j] |= (dp[i - 1][j] && a[i - 1] == c[i + j - 1]);
                }
                if (j > 0) {
                    dp[i][j] |= (dp[i][j-1] && b[j - 1] == c[i + j - 1]);
                }
            }
        if (dp[aL][bL])
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值