hdu1501 Zipper[简单DP]

Posted hardcoreyutian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1501 Zipper[简单DP]相关的知识,希望对你有一定的参考价值。

题目地址

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]的主要内容,如果未能解决你的问题,请参考以下文章

hdu1501 Zipper--DFS

HDU 1501 Zipper

HDU 1501 Zipper(dfs)

hdu1501 Zipper--DFS

hdu1501&amp;&amp;poj2192 Zipper(DFS)

HDU 1501 Zipper(记忆化搜索)