剑指offer打卡Day15:矩形覆盖

剑指offer打卡Day15: 矩形覆盖

题目描述

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

比如n=3时,2*3的矩形块有3种覆盖方法:
在这里插入图片描述

示例

输入

4

返回值

5

解析:

  • 依照题目进行推导,并由此总结规律

    • 推导过程如图:
      在这里插入图片描述

    • 由图中的结论不难看出这是一个斐波那契数列了,但具体是如何实现?

      • 以从n=3n=4推导n=5的排列

      在这里插入图片描述

      • 以从n=3n=4推导n=5的排列

        在这里插入图片描述

    • 不难得出结论:

      • 第n次组合数包含 由n-1加上一个竖着的矩形

      • 第n次组合数包含 由n-2加上两个横着的矩形

      • 递归公式为:

               |—— f[1] = 1 
        f[n] = |—— f[2] = 2
               |—— f[n-1] + f[n-2]  (n>2)
        
    • 因此代码可以由递归,动态规划等思路完成

解答:

//递归:
public int rectCover_withRecursion(int target) {
    if (target < 1) {
        return 0;
    } else if (target == 1 || target == 2) {
        return target;
    } else {
        return rectCover(target-1) + rectCover(target-2);
    }
}
//动态规划:
public int rectCover_withDp(int target) {
    if(target == 1 || target == 0 || target == 2){
        return target;
    }
    int[] dp = new int[target+1];
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    for(int i = 3; i <= target; i++){
        dp[i] = dp[i-1] + dp[i-2];
    }
    return dp[target];
}
//动态规划继续优化
public int rectCover——withDpImprove(int target) {
    if(target==1 || target==2) return target;
    int a = 1, b=2;
    int c = 0;
    for(int i=3;i<=target;i++){
        c = b+a;
        a = b;
        b = c;
    }
    return c;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值