动态规划:青蛙跳台阶、变态跳台阶

青蛙跳台阶问题是一个简单的动态规划问题。

问题1:普通跳台阶

一只青蛙可以一次跳 1 级台阶或者一次跳 2 级台阶,例如:

  1. 跳上第 1 级台阶只有一种跳法:直接跳 1 级即可。
  2. 跳上第 2 级台阶有两种跳法:每次跳 1 级,跳两次;或者一次跳 2 级。

问要跳上第 n 级台阶有多少种跳法?

很多人喜欢正向思考,使用暴力求解,但往往这是一个很复杂的问题。我们可以反过来思考:

如果我们要跳上第 n 级台阶,该怎么跳?此时问题就简单多了,答案是,要么从第 n1 级台阶跳一级上来,要么从第 n2 级台阶跳两级上来,除此,青蛙再也没有其他的方法可以跳上第 n 级台阶。

我们令 f(n) 表示从第一级台阶跳上第 n 级台阶有几种跳法。则有如下递推公式:

f(n)=f(n1)+f(n2)

是不是很熟悉,它不就是斐波那契数列吗,代码就很简单啦:

int jumpFloor(int number) {
    int g = 1, f = 2;
    while (number-- > 1) {
        f += g;
        g = f - g;
    }
    return g;
}

问题2:变态跳台阶

变态跳台阶问题是这样的:如果青蛙可以一次跳 1 级,也可以一次跳 2 级,一次跳 3 级,…,一次跳 n 级。问要跳上第 n 级台阶有多少种跳法?

同样的,我们采用逆向思维,将问题改为:跳上第 n 级台阶该怎么跳?答案如下:

要跳上第 n 级台阶,可以从第 n1 级台阶一次跳上来,也可以可以从第 n2 级台阶一次跳上来,也可以可以从第 n3 级台阶一次跳上来,…,也可以可以从第 1 级台阶一次跳上来。那么问题就很简单啦,同样的,令 f(n) 表示从第一级台阶跳上第 n 级台阶有几种跳法。则有如下递推公式:

f(n)=f(n1)+f(n2)+...+f(1)

同时, f(n1) 也可以表示如下:

f(n1)=f(n2)+f(n3)+...+f(1)

所以,由上面两个公式可知:
f(n)=2f(n1)=4f(n2)=8f(n3)=...

即:
f(n)=2f(n1)=22f(n2)=23f(n3)=...=2n1f(n(n1))=2n1f(1)

因为 f(1)=1 ,所以 f(n)=2n1

代码如下:

int square(int a) { return a * a; }
int power2(int n) { // 计算2的n次方
    if (0 == n) return 1;
    return n % 2 ? square(power2(n>>1))<<1 : square(power2(n>>1));
}

int jumpFloorII(int number) {
    return power2(number - 1);
}
  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值