码迷,mamicode.com
首页 > 其他好文 > 详细

[剑指offer] 矩形覆盖

时间:2016-04-28 10:41:43      阅读:227      评论:0      收藏:0      [点我收藏+]

标签:

题目描述

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

输入描述

一个大矩形

输出描述

覆盖的方法数

题目分析

设 被n个2*1的小矩形无重叠地覆盖的方法总数为 f(n)

  • 当n=1时,明显f(1)=1;

  • 当n=2时,只能两个都横着或两个都竖着放,有f(2)=2;

  • 当小矩形个数为n,来覆盖这个2*n的大矩形。第一步只有两种放法:

     ①竖着放,那么剩下的摆放总数为 f(n-1)

技术分享 

   ②横着放,那么剩下的摆放总数为 f(n-2)。因为它下面的那块也跟随着它的摆放而确定(必须是一个横着放的小矩形)。

技术分享 

很容易看出满足斐波那契数列。

斐波那契数列(Fibonacci sequence),又称黄金分割数列

在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)  

指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、…… 

可以得出递推公式:

     | 1     (n=0 )
f(n) =   | 1      (n=1 )
     | f(n-1)+f(n-2)  (n>=2)

解法一 (递归)  运行时间:924ms  占用内存:654k

public class Solution {
    public int RectCover(int target) {
        if(target<=1) return 1;
        return RectCover(target-1)+RectCover(target-2);
    }
}

递归效率不高,重复计算多,比如:

f(4) = f(3) + f(2);
      = f(2) + f(1) + f(1) + f(0);
      = f(1) + f(0) + f(1) + f(1) + f(0);

求f(4)就要计算三次f(1)和两次f(0),显然这是不行的。

解法二(动态规划)  运行时间:29ms 占用内存:629k

public class Solution {
    public int RectCover(int target) {
        if(target<=1) return 1;
        int i =1;//f(0)
        int j =1;//f(1)
        for(;target>=2;target--){
            j+=i;
            i=j-i;
        }
        return j;
    }
}

显然这个快很多,n>=2时,根据 f(n)=f(n-1)+f(n-2)进行依次计算,最后得出 f(target)并返回。

[剑指offer] 矩形覆盖

标签:

原文地址:http://blog.csdn.net/amazing7/article/details/51272179

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!