码迷,mamicode.com
首页 > 其他好文 > 详细

hdu1501 Zipper[简单DP]

时间:2019-07-14 16:33:16      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:顺序   inf   状态转移方程   blog   问题   clu   ||   最优   ems   

题目地址

hdu1501

题干

技术图片

代码和解释

最优子结构分析:设这三个字符串分别为a、b、c,如果a、b可以组成c,那么c的最后一个字母必定来自a或者b的最后一个字母。c去除最后一位,就变成由a-1和b或者a和b-1构成c-1的问题。
状态转移方程:DP[i][j]表示c中i个字符来自于a,j个字符来自于b,即由a的前i个字符和b的前j个字符组成c的前i+j个字符。DP[i][j]为1则真,为0则假。

/*给3个字符串,让你判断能不能组合前两个字符串来获得第3个字符串。前两个字符串可以被任意混合,但都必须保持原来的顺序。*/
/*输入:第一行输入一个1到1000的整数,表示样例的数量。一组样例一行。
字符串都只包含大小写字母,第3个字符串的长度必须等于前两个字符串长度之和,前两个字符串长度从1到200*/
/*输出:
Data set n: yes或Data set n: no,每组样例有一个输出。*/
#include<stdio.h>
#include<string.h>
int main()
{
    int T;
    char a[210];
    char b[210];
    char c[410];
    int len1,len2;
    int DP[210][210];//DP[i][j]指c中有i位来自a,j位来自b 
    int i,j;
    int count = 1;
    scanf("%d",&T);
    while(T--){
    scanf("%s%s%s",a+1,b+1,c+1);
    len1=strlen(a+1);
    len2=strlen(b+1);
    memset(DP,0,sizeof(DP));
        
        for(i=1;i<=len1;i++){
        if(a[i]==c[i]){
            DP[i][0]=1;
        }
    }
        
        for(j=1;j<=len2;j++){
        if(b[j]==c[j]){
        DP[0][j]=1;
        }
    }
        
        for(i=1;i<=len1;i++){
        for(j=1;j<=len2;j++){
        if((DP[i-1][j]&&a[i]==c[i+j])||(DP[i][j-1]&&b[j]==c[i+j])){
            DP[i][j]=1;
        }
        }
    }
        
        if(DP[len1][len2]==1){
        printf("Data set %d: yes\n",count);
    }
    else printf("Data set %d: no\n",count);
        count++;
    }
    return 0;
} 

这里的字符串输入是scanf("%s",a+1);而不是scanf("%s",a);我认为是为了方便理解第几位就是第几位,而且方便对DP[i][0]和DP[0][j]的处理。
注意几个字符串数组都要开的大一点,一开始我wa就是因为数组开成201,不够大。

参考

hdu1501最优子结构
hdu1501简单DP

hdu1501 Zipper[简单DP]

标签:顺序   inf   状态转移方程   blog   问题   clu   ||   最优   ems   

原文地址:https://www.cnblogs.com/hardcoreYutian/p/11184586.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!