zoukankan      html  css  js  c++  java
  • 洛谷 P1244 青蛙过河

    题目描述

    有一条河,左边一个石墩(A区)上有编号为1,2,3,4,…,n的n只青蛙,河中有k个荷叶(C区),还有h个石墩(D区),右边有一个石墩(B区),如下图所示。n只青蛙要过河(从左岸石墩A到右岸石墩B),规则为:

    (1)石墩上可以承受任意多只青蛙,荷叶只能承受一只青蛙(不论大小);

    (2)青蛙可以:A→B(表示可以从A跳到B,下同),A→C,A→D,C→B,D→B,D→C,C→D;

    (3)当一个石墩上有多只青蛙时,则上面的青蛙只能跳到比它大1号的青蛙上面。

    你的任务是对于给出的h,k,计算并输出最多能有多少只青蛙可以根据以上规则顺利过河?

    输入输出格式

    输入格式:

     

    两个整数h,k

     

    输出格式:

     

    一个整数,表示最多能有多少只青蛙可以根据以上规则顺利过河。

     

    输入输出样例

    输入样例#1: 复制
    2 3
    
    输出样例#1: 复制
    16
    思路:递推(dp)

    首先,青蛙只能往前跳,不能往后跳,而且只能12345这样排下去,所以要想使最多的青蛙到达对岸,只需使编号最大的青蛙首先跳到对岸(否则编号更大的青蛙就跳不过去了)。

    然后,要想使编号最大的青蛙首先跳到对岸,只需让河面上承载最多的青蛙。而荷叶上只能承载一只青蛙,所以需要让青蛙尽可能多地叠到石墩上。

    接下来便是核心内容:(f[i]表示当有k个荷叶,i个石墩时过河青蛙的最大数量)

    1、若有k个荷叶,没有石墩,则最多有k+1个青蛙。所以f[0]=k+1(不需要解释了吧);

    2、若有k个荷叶,1个石墩,则只需要使石墩上承载最多的青蛙。进一步分析,我们只需要将石墩当做对岸,这样就变成1的情况了。所以f[1]=f[0]+k+1;

    3、若有k个荷叶,2个石墩,则需要先让石墩1作为对岸,叠完后再让石墩2作为对岸。所以f[2]=f[1]+f[0]+k+1;

    继续往下推理,得到状态转移方程:f[h]=f[0]+f[1]+f[2]+……+f[h-1]+k+1;

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int h,k,sum;
    int f[10000];
    int main(){
        scanf("%d%d",&h,&k);
        f[0]=k+1;
        sum=f[0]+k+1;
        for(int i=1;i<=h;i++){
            f[i]=sum;
            sum+=f[i];
        }
        cout<<f[h];
    }
     
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    CLRS2e读书笔记—Chapter10
    CLRS2e读书笔记—Chapter6
    CLRS2e读书笔记—Chapter34 & Appendix A,B
    CLRS2e读书笔记—Chapter8
    CLRS2e读书笔记—Chapter5 & Appendix C
    CLRS2e读书笔记—Chapter7
    Haskell学习笔记<三>
    屏幕一直亮的问题
    对CCLabelTTF进行自动换行,显示打字效果
    XCODE 4.2打包发布
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7967465.html
Copyright © 2011-2022 走看看