NOI2000 青蛙過河[遞推]

也許更好的閱讀體驗

Description\mathcal{Description}

原題鏈接:
Comet OJ
洛谷

大小各不相同的一隊青蛙站在河左岸的石墩(記爲A)上,要過到對岸的石墩(記爲D)上去。河心有幾片菏葉(分別記爲Y1YmY1​…Ym​)和幾個石墩(分別記爲S1SnS1…Sn)。圖示如下:

49776cae2.md.png

青蛙的站隊和移動方法規則如下:

每隻青蛙只能站在荷葉、石墩,或者僅比它大一號的青蛙背上(統稱爲合法的落腳點);
一隻青蛙只有背上沒有其它青蛙的時候才能夠從一個落腳點跳到另一個落腳點;
青蛙允許從左岸A直接跳到河心的石墩、荷葉和右岸的石墩D上,允許從河心的石墩和荷葉跳到右岸的石墩D上;
青蛙在河心的石墩之間、荷葉之間以及石墩和荷葉之間可以來回跳動;
青蛙在離開左岸石墩後,不能再返回左岸;到達右岸後,不能再跳回;
假定石墩承重能力很大,允許無論多少隻青蛙都可呆在上面。但是,由於石墩的面積不大,至多隻能有一隻青蛙直接站在上面,而其他的青蛙只能依規則1落在比它大一號的青蛙的背上。
荷葉不僅面積不大,而且負重能力也有限,至多隻能有一隻青蛙站在上面。
每一步只能移動一隻青蛙,並且移動後需要滿足站隊規則;
在一開始的時候,青蛙均站在A上,最大的一隻青蛙直接站在石墩上,而其它的青蛙依規則6站在比其大一號的青蛙的背上。

青蛙希望最終能夠全部移動到D上,並完成站隊。

設河心有mm片荷葉和nn個石墩,請求出這隊青蛙至多有多少隻,在滿足站隊和移動規則的前提下,能從A過到D。

例如,在m=1且 n=1時,河心有一片荷葉Y1(Y1​)和一個石墩S1(S1​),此時至多有44只青蛙能夠過河(由小到大稱爲12341、2、3、4),過河的一種方法爲:

12449fec1.md.png

此例中,當河心有一片荷葉和一個石墩時,4只青蛙能夠跳動9步過河。

輸入描述

僅有兩行,每一行僅包含一個整數和一個換行/回車符。第一行的數字爲河心的石墩數n0n25n(0≤n≤25),第二行爲荷葉數m0m25m(0≤m≤25)

輸出描述

僅包含一個數字和一個換行/回車符。該數字爲在河心有nn個石墩和mm片荷葉時,最多能夠過河的青蛙的只數。

Solution\mathcal{Solution}

簡單來說就是在石墩上青蛙可以類似HanoiHanoi問題()(漢諾塔)地疊着
我們想疊得越多越好,顯然我們既然有辦法把它疊起來,用疊的逆過程就可以把它們全部合法的放到河對岸
所以我們只要考慮如何疊
設有nn片荷葉,kk個石墩
k=0k=0,那麼我們在每片荷葉上放一隻青蛙,然後從岸上直接跳到對面一隻青蛙,可以有n+1n+1只青蛙過岸
k=1k=1,那麼我們可以在這個石墩上疊n+1n+1只青蛙,然後就又變爲k=0k=0的情況
類似地,每多一個石墩就可以利用原來的k1k-1個石墩把它們的青蛙全部放到這上面來,這樣就增加了一倍的青蛙可以過岸

換個想法,我們可以將每個石墩當成對岸的石墩,然後我們就先直接跳一個青蛙上來,再把當前的青蛙fk11f_{k-1}-1全部轉移到這個石墩上面,然後原來的石墩就都空了,於是可以再把原來石墩上再放fk11f_{k-1}-1,這樣最後能過岸的就多了一倍

也就是有(n+1)2k(n+1)*2^{k}可以過河

Code\mathcal{Code}

/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年08月27日 星期二 14時58分07秒
*******************************/
#include <cstdio>
#include <fstream>
#define ll long long
using namespace std;
ll n,k;
int main()
{
	scanf("%lld%lld",&n,&k);
	printf("%lld\n",(k+1)*(1<<n));
	return 0;
}

如有哪裏講得不是很明白或是有錯誤,歡迎指正
如您喜歡的話不妨點個贊收藏一下吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章