【算法】剑指offer-青蛙跳台阶&&矩形覆盖(2)

文章目录

青蛙跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果).

方法一:简单动归方式
状态定义:f(i): 跳到i台阶的总跳法
状态递推:f(i) = f(i-1)+f(i-2)

  • 可以从第i-1阶台阶跳到第i阶台阶 (跳一级)
  • 也可也从第i-2阶台阶跳到第i阶台阶 (跳二级)

初始状态: f(0) = 1(0台阶,就是起点,到达0台阶的方法有一种,就是不跳[这里可能有点奇怪,但是想想,如果方法次数为0,就说明不可能开始…]), f(1) = 1

class Solution {
public:
    int jumpFloor(int number) {
        if(number == 0 || number == 1)
        {
            return 1;
        }
        if(number == 2)  
        {
            return 2;
        }
        
        //dp[n] = dp[n-1] + dp[n-2]
        //为了让跳法和跳上的台阶数对应
        int\* dp = new int[number+1];
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 2;
        //计算跳上第number阶台阶的跳法,从跳上第三阶开始需要计算
        for(int i = 3;i<=number;i++)
        {
            dp[i] = dp[i-1]+dp[i-2];
        }
        int ans = dp[number];//先记录答案,跳上第number阶台阶的跳法
        delete[] dp;//要释放内存
        return ans;
    }
};

方法2:直接迭代,细看这个方程,本质就是斐波那契数列

注意:此处是从i=2开始,计算到 i=number,i=2开始计算的f3是跳第三级台阶的

class Solution {
    public:
    int jumpFloor(int number) {
        if(number == 0 || number == 1)
        {
            return 1;
        }
        if(number == 2)  
        {
            return 2;
        }
        int f1 = 1;//跳上第1级台阶的方法
        int f2 = 2;//跳上第2级台阶的方法
        int f3;
        //从跳上第三个台阶的方法数开始计算
        for(int i = 3;i<=number;i++)
        {
            f3 = f2+f1;
            f1 = f2;
            f2 = f3;
        }
        return f3;   
    }
};

//写法2:
//从跳上第三个台阶的方法数开始计算
while(number>2)
{
    f3 = f2+f1;
    f1 = f2;
    f2 = f3;
    number--;
}
return f3;   


矩形覆盖

我们可以用 2*1 的小矩形横着或者竖着去覆盖更大的矩形.请问用n个 2*1 的小矩形无重叠地覆盖一个 2*n 的大矩形,总共有多少种方法?

比如n=3时, 2*3 的矩形块有3种覆盖方法:

image-20220405093847010

用n个2\*1的小矩形无重叠地覆盖一个2\*n的大矩形
每次放置的时候,无非两种放法,横着放或竖着放:
	其中,横着放一个之后,下一个的放法也就确定了,故虽然放置了两个矩形,但属于同一种放法,如果横着放一个,下一个必定也要横着放,所以要依次横着放两个
	其中,竖着放一个之后,本轮放置也就完成了,也属于一种方法
所以,当2\*n的大矩形被放满的时候,它无非就是从上面两种放置方法放置来的
我们继续使用dp来进行处理,当然后续会发现,斐波那契数列的方式也可以处理

状态定义:f(n) : 用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形所用的总方法数
状态递推:f(n) = f(n-1)【最后一个竖着放】 + f(n-2)【最后两个横着放】
初始化:f(1) = 1,f(2) = 2,f(0)=0, 注意f(0)我们这个可以不考虑,题目说了,约定 n == 0 时,输出 0

表达式含义
f(n)用2*1的小矩形无重叠的覆盖一个2*n的大矩形的总方法数
f(n-1)用2*1的小矩形无重叠的覆盖一个2*(n-1)的大矩形的总方法数
f(n-2)用2*1的小矩形无重叠的覆盖一个2*(n-2)的大矩形的总方法数

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值