33.矩形覆盖

本文探讨使用2*1小矩形无重叠覆盖2*n大矩形的方法数量,通过递归与迭代算法解决,归纳出f(n)=f(n-1)+f(n-2)的递推公式,并推广至1*m方块覆盖m*n区域的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

我们可以用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.youkuaiyun.com/heda3/article/details/86773270

31.跳台阶https://blog.youkuaiyun.com/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;
    }
};

参考:https://www.nowcoder.com/questionTerminal/72a5a919508a4251859fb2cfb987a0e6

题目描述 看下面的五张 9 x 8 的图像: ........ ........ ........ ........ .CCC.... EEEEEE.. ........ ........ ..BBBB.. .C.C.... E....E.. DDDDDD.. ........ ..B..B.. .C.C.... E....E.. D....D.. ........ ..B..B.. .CCC.... E....E.. D....D.. ....AAAA ..B..B.. ........ E....E.. D....D.. ....A..A ..BBBB.. ........ E....E.. DDDDDD.. ....A..A ........ ........ E....E.. ........ ....AAAA ........ ........ EEEEEE.. ........ ........ ........ ........ 1 2 3 4 5 现在,把这些图像按照 1—5 的编号从下到上重叠,第 1 张在最下面,第 5 张在最顶端。如果一张图像覆盖了另外一张图像,那么底下的图像的一部分就变得不可见了。我们得到下面的图像: .CCC.... ECBCBB.. DCBCDB.. DCCC.B.. D.B.ABAA D.BBBB.A DDDDAD.A E...AAAA EEEEEE.. 对于这样一张图像,计算构成这张图像的矩形图像从底部到顶端堆叠的顺序。 下面是这道题目的规则: 矩形的边的宽度为 1 ,每条边的长度都不小于 3 。 矩形的每条边中,至少有一部分是可见的。注意,一个角同时属于两条边。 矩形写字母表示,并且每个矩形的表示符号都不相同。 输入格式 第一行 两个用空格分开的整数:图像高 H (3 <= H <=30) 和图像宽 W (3 <= W <= 30) 。 第二行到第 H+1 行 H 行,每行 W 个字母。 输出格式 按照自底向上的顺序输出字母。如果有不止一种情况,按照字典顺序输出每一种情况(至少会有一种合法的顺序)。 样例 #1 样例输入 #1 9 8 .CCC.... ECBCBB.. DCBCDB.. DCCC.B.. D.B.ABAA D.BBBB.A DDDDAD.A E...AAAA EEEEEE.. 样例输出 #1 EDABC 要求: 1.c++ 2.用DAG来做 3.变量名在5字符以内 4.可以写函数 5.变量名
最新发布
08-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heda3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值