【数学、动态规划】[NOI2000] 青蛙过河

题目

题意难懂,建议多读几遍
大小各不相同的一队青蛙站在河左岸的石墩(记为 A A A)上,要过到对岸的石墩(记为 D D D)上去。河心有几片荷叶(分别记为 Y 1 … Y m Y_1 …Y_m Y1Ym)和几个石墩(分别记为 S 1 … S n S_1 …S _n S1Sn )。图示如下:
在这里插入图片描述

青蛙的站队和移动方法规则如下:

  • 每只青蛙只能站在荷叶、石墩,或者仅比它大一号的青蛙背上(统称为合法的落脚点);
  • 一只青蛙只有背上没有其它青蛙的时候才能够从一个落脚点跳到另一个落脚点;
  • 青蛙允许从左岸 A 直接跳到河心的石墩、荷叶和右岸的石墩 D 上,允许从河心的石墩和荷叶跳到右岸的石墩 D 上,但在左岸 A 和右岸 D 上的青蛙仍然要站在地上或仅比它大一号的青蛙背上
  • 青蛙在河心的石墩之间、荷叶之间以及石墩和荷叶之间可以来回跳动;
  • 青蛙在离开左岸石墩后,不能再返回左岸;到达右岸后,不能再跳回
  • 假定石墩承重能力很大,允许无论多少只青蛙都可呆在上面。但是,由于石墩的面积不大,至多只能有一只青蛙直接站在上面,而其他的青蛙只能依规则 1 落在比它大一号的青蛙的背上。
  • 荷叶不仅面积不大,而且负重能力也有限,至多只能有一只青蛙站在上面(也就是说在荷叶上的青蛙不能同时踩在其它青蛙的背上)
  • 每一步只能移动一只青蛙,并且移动后需要满足站队规则;
  • 在一开始的时候,青蛙均站在 A 上,最大的一只青蛙直接站在石墩上,而其它的青蛙依规则 1 站在比其大一号的青蛙的背上。

青蛙希望最终能够全部移动到 D 上,并完成站队。

设河心有 m m m 片荷叶和 n n n 个石墩,请求出这队青蛙至多有多少只,在满足站队和移动规则的前提下,能从 A 过到 D。

思路

显而易见,如果河面只有 m m m 片荷叶,则最多能让 m + 1 m+1 m+1 只青蛙完成以上操作(让前 m m m 只青蛙跳到荷叶上,最后一只直接跳到对岸,剩余的青蛙再按照顺序从大到小跳到对岸)。

考虑记当河面有 i i i 个石墩时最多可以有 d p i dp_i dpi 只青蛙(不考虑荷叶的情况,有荷叶同理),则 d p i = d p i − 1 × 2 dp_i = dp_{i - 1} \times 2 dpi=dpi1×2。以下为证明:

如果有 i − 1 i - 1 i1 个石墩时 d p i dp_i dpi 只青蛙满足题意,则有 i i i 个石墩时前 d p i − 1 dp_{i - 1} dpi1 只青蛙必然能够从大到小排列在河中间的某一个石墩上,剩下 d p i − 1 dp_{i-1} dpi1 只青蛙再跳到河对面(此时河面刚好只剩下 i − 1 i - 1 i1 个可用的石墩),最后再将石墩上的 d p i − 1 dp_{i - 1} dpi1只青蛙挪动到河对岸即可。

综上所述, d p i = 2 d p i − 1 dp_i = 2dp_{i - 1} dpi=2dpi1,因此 d p i = 2 i dp_i = 2^i dpi=2i,答案为 ( m + 1 ) 2 n (m+1)2^n (m+1)2n

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
signed main() {
	scanf("%lld%lld",&n,&m);
	m++;
	while(n--) m *= 2;
	printf("%lld\n",m);
    return 0;
}
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值