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

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

时间: 2024-07-29 10:24:18

hdu1501 Zipper[简单DP]的相关文章

POJ 3250 Bad Hair Day 简单DP 好题

Description Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-conscious about her messy hairstyle, FJ wants to count the number of other cows that can see the top of other cows' heads. Each cow i has a sp

hdu1207 汉诺塔II 简单dp

本文出自:http://blog.csdn.net/svitter 题意:汉诺塔,多了一根柱子,问你寻找最快的移动次数. dp [ n ] = dp [ n - j ] * 2 + pow( 2, j ) - 1; 就是把j个汉诺塔移到一根上dp[ n - j ],然后就是普通的汉诺塔问题,即2^n - 1次移动, 然后把剩下的移动过去dp [ n - j ]. 注意pow(2, j )可能超出long long int范围.写二的次方的时候也可用移位算法. #include <iostream

POJ1088:滑雪(简单dp)

题目链接:  http://poj.org/problem?id=1088 题目要求: 一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小.求可以滑落的最长长度. 题目解析: 首先要先排一下序,因为只能高度递减才能滑行.之后就很简单了,就是简单DP. 即:要求的滑坡是一条节点递减并依次相邻的最长路径,可以先根据高度将所有的点进行排序,在i点的时候,遍历0~i-1个点(升序排序,i前面的点的高度一定小于等于i),取相邻点间的大的路径长度 代码如下: #include <iostream

hdu 1087 简单dp

思路和2391一样的.. <span style="font-size:24px;">#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int inf=(0x7f7f7f7f); int main() { int a; int s[10005]; int w[10005];

hdu1087 简单DP

I - 简单dp 例题扩展 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description Nowadays, a kind of chess game called “Super Jumping! Jumping! Jumping!” is very popular in HD

2014 HDU多校弟九场I题 不会DP也能水出来的简单DP题

听了ZWK大大的思路,就立马1A了 思路是这样的: 算最小GPA的时候,首先每个科目分配到69分(不足的话直接输出GPA 2),然后FOR循环下来使REMAIN POINT减少,每个科目的上限加到100即可 算最大GPA的时候,首先每个科目分配到60分,然后FOR循环下来使REMAIN POINT减少,每个科目的上限加到85即可,如果还有REMAIN POINT,就FOR循环下来加到100上限即可 不会DP 阿 QAQ 过段时间得好好看DP了  =  = 于是默默的把这题标记为<水题集> //

Codeforces 41D Pawn 简单dp

题目链接:点击打开链接 给定n*m 的矩阵 常数k 下面一个n*m的矩阵,每个位置由 0-9的一个整数表示 问: 从最后一行开始向上走到第一行使得路径上的和 % (k+1) == 0 每个格子只能向或走一步 求:最大的路径和 最后一行的哪个位置作为起点 从下到上的路径 思路: 简单dp #include <cstdio> #include <algorithm> #include<iostream> #include<string.h> #include &

HDU 4826 简单DP

Problem Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,且只能向上向下向右走以前没有走过的格子,每一个格子中都有一些金币(或正或负,有可能遇到强盗拦路抢劫,度度熊身上金币可以为负,需要给强盗写欠条),度度熊刚开始时身上金币数为0,问度度熊走出迷宫时候身上最多有多少金币? Input 输入的第一行是一个整数T(T < 200),表示共有T组数据.每组数据的

UVA - 11584 划分字符串的回文串子串; 简单dp

/** 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34398 UVA - 11584 划分字符串的回文串子串: 简单dp 题目大意: 给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串.问最少可以分割成多少个. 定义:dp[i]表示前0~i内的字符串划分成的最小回文串个数: dp[i] = min(dp[j]+1 | j+1~i是回文串); 先预处理flag[i][j]表示以i~j内的字符串为回文串