洛谷 P1244 青蛙過河
阿新 • • 發佈:2017-12-04
clas algo ring 最大數 arr www. cstring 承載 否則
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]; }
洛谷 P1244 青蛙過河