HDU 1501 & POJ 2192 Zipper(dp记忆化搜索)

题意:给定三个串,问c串是否能由a,b串任意组合在一起组成,但注意a,b串任意组合需要保证a,b原串的顺序 例如ab,cd可组成acbd,但不能组成adcb。

分析:对字符串上的dp还是不敏感啊,虽然挺裸的....dp[i][j] 表示a串前i个,b串前j个字母能组成c串前i+j个字母。所以dp[lena-1][lenb-1] = 1; 就行了。

从后往前找就很好找了,从c串最后一个字符开始递归搜索。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
# define MAX 222
using namespace std;

char a[MAX],b[MAX],c[MAX*2];
int dp[MAX][MAX];
int lena,lenb,lenc;

int dfs(int i,int j,int k) {
    //cout << i << ' ' << j << ' ' << k << endl;
    //cout << a[i] << ' ' <<  b[j] << ' ' << c[k]  << endl;
    if(dp[i][j] != -1 && i >=0 && j >=0) return dp[i][j];
    if(k == 0 && (a[i] == c[k] || b[j] == c[k])) return 1;
    if(i != -1 && a[i] == c[k]) {
        dp[i][j] = max(dp[i][j],dfs(i-1,j,k-1));
    }
    if(j != -1 && b[j] == c[k]) {
        dp[i][j] = max(dp[i][j],dfs(i,j-1,k-1));
    }
    if(dp[i][j] == -1)
        dp[i][j] = 0;
    return dp[i][j];
}

int main() {
    //freopen("D:\\in.txt","r",stdin);
    //freopen("D:\\out2.txt","w",stdout);
    int T;
    int casee = 1;
    cin >> T;
    while(T --) {
        memset(dp,-1,sizeof(dp));
        scanf("%s%s%s",a,b,c);
        printf("Data set %d: ",casee++);
        lena = strlen(a);
        lenb = strlen(b);
        lenc = strlen(c);
        //cout << lena << ' ' << lenb << ' ' << lenc << endl;
        if(lena + lenb != lenc) {
            puts("no");
            continue;
        }
        if(dfs(lena-1,lenb-1,lenc-1)) {
            puts("yes");
        }
        else puts("no");
    }
    return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值