33.矩形覆盖

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

题目描述

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


思路:


可以从第n-1到一步到n,这样的话有多少种方案覆盖到n-1就有多少种方案覆盖到n,另外我们也可以从n-2覆盖到n,有多少种方案覆盖到n-2就有多少种方案覆盖到n.?可以这样认为2*1的矩形有两种可能;1)竖着2*1 2)横着 此时必须是两块2*1的矩形拼成2*2 此时就好理解了


也可以也可以举例子归纳:


分别为当n=1时  1种


n=2时  2种方式


n=3时  3种方式


n=4 时 5种方式


f(n) = f(n-1) + f(n - 2), (n > 2)


推广:


相应的结论应该是:


(1)1 * 3方块 覆 盖3*n区域:f(n) = f(n-1) + f(n - 3), (n > 3)


(2) 1 *4 方块 覆 盖4*n区域:f(n) = f(n-1) + f(n - 4),(n > 4)


更一般的结论,如果用1*m的方块覆盖m*n区域,递推关系式为f(n) = f(n-1) + f(n-m),(n > m)。


参考;https://www.nowcoder.com/profile/2951934/codeBookDetail?submissionId=16796833


类似之前的文章:


30.斐波那契数列https://blog.csdn.net/heda3/article/details/86773270


31.跳台阶https://blog.csdn.net/heda3/article/details/86773998


递归解法:


class Solution {

public:

   int rectCover(int number) {

       if (number < 1)

       {

           return 0;

       }

       else if (number == 1 || number == 2)

       {

           return number;

       }

       else

       {

           return rectCover(number-1) + rectCover(number-2);

       }

   }

};

迭代解法:


1需要辅助数组


class Solution {

public:

   int rectCover(int number) {

       int rC[number+1];

       rC[1]=1;

       rC[2]=2;

       if (number <= 1)

       {

           return number;

       }

      for(int i=3;i<=number;i++)

      {

          rC[i]= rC[i-1]+ rC[i-2];

       

      }

       return rC[number];

   }

};

迭代:递推解法1


2不需要辅助数组,需要3个变量


class Solution {

public:

   int rectCover(int number) {

       int rC1=1,rC2=1,rC3=1;

      if(number <= 1)

       {

           return number;

       }

      for(int i=2;i<=number;i++)

      {

          rC3=rC1+rC2;

          rC1=rC2;

          rC2=rC3;

      }

       return rC3;

   }

};

注意:如果n=0那么返回是0


错误代码


class Solution {

public:

   int rectCover(int number) {

       if(number<=0)

           return 1;//像这样是错的

       int  temp1=1,temp2=1,temp3=1;

       while(--number){

           temp3=temp1+temp2;

           temp1=temp2;

           temp2=temp3;

       }

       return temp3;

}

};

递推2


需要两个变量


class Solution {

public:

   int rectCover(int number) {

       if ( number < 1 )

           return 0;

       int g = 1, f = 2;

       while ( --number )

       {

           //只需要两个变量

           f = f + g;

           g = f - g;

       }

       return g;

   }

};

目录
相关文章
|
存储 JSON 安全
Python中数据类转换为JSON的方法
Python中数据类转换为JSON的方法
415 0
|
Shell
Ubuntu20.04安装anaconda并默认激活conda base环境(步骤详细/操作简单实用)
Ubuntu20.04安装anaconda并默认激活conda base环境方法
20605 0
|
存储 Java 程序员
Java 日志框架解析:汇总及最佳实践
在java的世界里有许多实现日志功能的工具,最早得到广泛使用的是 log4j,现在比较流行的是slf4j+logback。作为开发人员,我们有时候需要封装一些组件(二方包)提供给其他人员使用,但是那么多的日志工具,根本没法保证每个组件里都能使用约定好的日志工具,况且还有很多第三方的包,鬼知道他会用什么日志工具。假如一个应用程序用到了两个组件,恰好两个组件使用不同的日志工具,那么应用程序就会有两份日志输出了,蛋疼吧。。 下面简单介绍下常见的日志工具:
12089 2
Java 日志框架解析:汇总及最佳实践
|
消息中间件 存储 监控
消息队列原理和选型:Kafka、RocketMQ 、RabbitMQ 和 ActiveMQ
常用的消息队列主要这 4 种,分别为 Kafka、RabbitMQ、RocketMQ 和 ActiveMQ,主要介绍前三,不BB,上思维导图!
3432 0
消息队列原理和选型:Kafka、RocketMQ 、RabbitMQ 和 ActiveMQ
|
设计模式 微服务
设计模式问题之在软件设计中,“模块”如何定义和区分
设计模式问题之在软件设计中,“模块”如何定义和区分
152 0
|
SQL 存储 NoSQL
MongoDB和MySQL的区别
前言: MySQL与MongoDB都是开源的常用数据库,但是MySQL是传统的关系型数据库,MongoDB则是非关系型数据库,也叫文档型数据库,是一种NoSQL的数据库。它们各有各的优点,关键是看用在什么地方。
10674 23
|
存储 NoSQL Redis
redis zset底层数据结构
zset底层存储结构  zset底层的存储结构包括ziplist或skiplist,在同时满足以下两个条件的时候使用ziplist,其他时候使用skiplist,两个条件如下: 有序集合保存的元素数量小于128个 有序集合保存的所有元素的长度小于64字节  当ziplist作为zset的底层存储结构时候,每个集合元素使用两个紧挨在一起的压缩列表节点来保存,第一个节点保存元素的成员,第二个元素保存元素的分值。
15901 1
|
人工智能
欢迎新同事!AI 001号
欢迎新同事!AI 001号
168 0
|
监控 安全 Java
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)
637 0
《SpringBoot启动流程三》:两万+字图文带你debug源码分析SpringApplication准备阶段(含配置文件加载时机、日志系统初始化时机)