刷题11 矩形覆盖问题

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

思路: 这种题开始肯定要找规律, 看了看, n = 1时, 一种方法; n = 2时, 两种方法; n = 3时,三种方法; n = 4时, 五种方法; ... ; 很自然想起了斐波那契数列。

证明一下:

设 n 列一共有 f(n) 种无重叠的覆盖方法,先上一个自己画的图方便理解。

1、对于n > 2的情况:首先我们可以知道小矩形是2 * 1,整个矩形为2 * n,所以我们在填充的时候只有横着填充跟竖着填充。 所以思路就是将从第1列填充到第n列的情况分解.

怎么分解呢,然后我又画了下面这个图, 方便理解。

我想求从A到G总共多少中走法,咋求呢?   我先分解, 在第一步我有两种走法, 要么走B要么走C,然后B往后又有两种走法,C往后又有...

所以,说这么多,对于矩形填充所有情况, 那么先走第一步, 两种情况:竖着放或者横着放。

(1)对于第一步竖着放:  直接占据一竖列就OK了, 然后还剩下 n-1 列, 而n-1 列有 f(n-1) 种填充方法, 所以第一步竖着放总共有 1 * f(n-1) = f(n-1) 种方法;

(2)对于第一步横着放:  先放一个 2 * 1 小矩形,让它占据第一行第一、二列, 此时还剩下 n-2 列加上一个第二行第一、二列的区域。 我们难以用科学的方法表示出来, 怎么办?那就继续分解。

对于第二行第一、二列的区域,我们只存在唯一方式就是横着放上小矩形, 这样操作之后还剩下 n-2 列有 f(n-2) 种填充方法, 所以第一步横着放总共有 1 * 1 * f(n-2) = f(n-2) 种方法。

那么好了, 将这两个合并就是n列一共的方法数了, 即 f(n-1) + f(n-2) = f(n) 。看到这个式子是不是很熟, 对, 斐波那契数列。

2、那好,现在考虑到 n = 2 的情况, 不用 f(n-1) + f(n-2) = f(n) 这个公式, 更不要直接穷举, 用1中的思想考虑,可以得到:  f(2) = 1 + 1 * 1 = 2 。

那现在可以写代码了:

 1 class Solution {
 2 public:
 3     int rectCover(int number) {
 4         if(number < 3)
 5             return number;
 6         int first = 1;
 7         int second = 2;
 8         for(int i = 3; i <= number; i++)
 9         {
10             second = first + second;
11             first = second - first;
12         }
13         return second;
14     }
15 };

顺便想一下, 假如用 3 * 1 的小矩形填充 3 * n 的大矩形呢?

我们还是用 f(n) 表示 n 列的所有方法,第一步还是分两种情况:

(1)横着放:  横着放占了三列, 剩下 n-3 列, 总共情况为 1 * 1 * f(n-3) = f(n-3)

(2)竖着放: 竖着放了一列, 剩下 n-1 列, 总共情况为 1 * f(n-1) = f(n-1)

所以 f(n) = f(n-1) + f(n-3)

接下来还有其他变形都OK了。

时间: 2024-11-10 18:11:50

刷题11 矩形覆盖问题的相关文章

刷题 11/05

从昨天开始刷题,但是昨天比较懒,没有总结一下.今天开始总结一下刷题什么的遇到的bug和之前不注意的事情. 顺时针旋转矩阵 有一个NxN整数矩阵,请编写一个算法,将矩阵顺时针旋转90度. 给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于300. 很简单的矩阵变换,我是通过两次矩阵变换得到的,首先对角线交换,然后左右翻转就可以了. class Rotate: def rotateMatrix(self, mat, n): c = [[0 for i in range(0

刷题总结——道路覆盖(ssoj)

题目: 题目描述 Tar 把一段凹凸不平的路分成了高度不同的 N 段(每一段相同高度),并用 H[i] 表示第 i 段高度.现在 Tar 一共有 n 种泥土可用,它们都能覆盖给定的连续的 k 个部分.对于第 i 种泥土,它的价格为 C[i],可以使得区间 [i,min(n,i+k-1)] 的路段的高度增加 E[i].Tar 要设定一种泥土使用计划,使得使用若干泥土后,这条路最低的高度尽量高,并且这个计划必须满足以下两点要求:(1)每种泥土只能使用一次.(2)泥土使用成本必须小于等于 M .请求出

刷题11. Container With Most Water

一.题目说明 11.Container With Most Water,这个题目难度是Medium. 二.我的做法 乍一看,简单啊,两个for循环就可以了,我在本地写的. #include<iostream> #include<vector> #include<math.h> using namespace std; class Solution{ public: int maxArea(vector<int> &height){ int max =

面试刷题11:java系统中io的分类有哪些?

随着分布式技术的普及和海量数据的增长,io的能力越来越重要,java提供的io模块提供了足够的扩展性来适应. 我是李福春,我在准备面试,今天的问题是: java中的io有哪几种? java中的io分3类: 1,BIO ,即同步阻塞IO,对应java.io包提供的工具:基于流模型,虽然直观,代码实现也简单,但是扩展性差,消耗资源大,容易成为系统的瓶颈: 2,NIO,同步非阻塞io,对应java.nio包提供的工具,基于io多路复用:核心类: Channel ,Selector , Buffer ,

NOIP2002 矩形覆盖

题四 矩形覆盖(存盘名NOIPG4) [问题描述]: 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一. 这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴.当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4.问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢.约定:

剑指Offer系列之题11~题15

目录 11.矩形覆盖 12.二进制中1的个数 13. 数值的整数次方 14.调整数组顺序使奇数位于偶数前面 15.链表中倒数第k个结点 11.矩形覆盖 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形.请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 比如n=3时,2*3的矩形块有3种覆盖方法: 斐波那契数列的应用 第一次竖着放一块类比为走一步,第一次横着放两块类比为走两步 代码与上面的斐波那契数列类题目类似,此处不再赘述:剑指Offer系列之题6~题10. 12.

第十五周oj刷题—— Problem C: 矩形类中运算符重载【C++】

Description 定义一个矩形类,数据成员包括左下角和右上角坐标,定义的成员函数包括必要的构造函数.输入坐标的函数,实现矩形加法,以及计算并输出矩形面积的函数.要求使用提示中给出的测试函数并不得改动. 两个矩形相加的规则是:决定矩形的对应坐标分别相加,如 左下角(1,2),右上角(3,4)的矩形,与 左下角(2,3),右上角(4,5)的矩形相加,得到的矩形是 左下角(3,5),右上角(7,9)的矩形. 这个规则没有几何意义,就这么定义好了. 输出面积的功能通过重载"<<&quo

第十五周oj刷题——Problem B: 矩形类定义【C++】

Description 定义一个矩形类,数据成员包括左下角和右上角坐标,定义的成员函数包括必要的构造函数.输入坐标的函数,以及计算并输出矩形面积的函数.要求使用提示中给出的测试函数并不得改动. Input 四个数,分别表示矩形左下角和右上角顶点的坐标,如输入3.7 0.4 6.5 4.9,代表左下角坐标为(3.7, 0.4),右上角坐标为(6.5, 4.9). Output 输出一共有3行(请参考提示(hint)中的main函数): 第一行:由输入的坐标确定的矩形对象p1的面积 第二行:由对象复

2017年11月1日刷题记录 | 普及组

写在前面 哇Cys好菜啊! 哇Cys连普及组都不会打了啊! 哇要Noip了好紧脏啊! 哇Cys要开始刷题了 然后重点是Cys好菜菜菜菜菜菜啊!!!! 以下题目来自题库比赛 Task-1  A-B 题目描述 出题是一件痛苦的事情! 题目看多了也有审美疲劳,于是我舍弃了大家所熟悉的A+B Problem,改用A-B了哈哈! 好吧,题目是这样的:给出一串数以及一个数字C,要求计算出所有A-B=C的数对的个数.(不同位置的数字一样的数对算不同的数对) 输入输出格式 输入格式: 第一行包括2个非负整数N和