骨牌铺方格(递推)

这篇博客探讨了一个经典的递推问题,即如何计算在2×n的长方形方格中使用1×2骨牌铺满的所有方案数。通过分析不同尺寸的方格铺放情况,作者揭示了状态转移方程F(n)=F(n-1)+F(n-2),并提供了两种不同的推导思路。此外,还通过一个补充例题展示了如何处理更复杂的骨牌铺放问题,进一步巩固了递推问题的解决方法。

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

原题链接

Problem Description

在2 × n的一个长方形方格中,用一个1 × 2的骨牌铺满方格,输入n ,输出铺放方案的总数.例如n=3时,为2 × 3方格,骨牌的铺放方案有三种,如下图:在这里插入图片描述

Input

输入数据由多行组成,每行包含一个整数n,表示该测试实例的长方形方格的规格是2×n (0<n<=50)。

Output

对于每个测试实例,请输出铺放方案的总数,每个实例的输出占一行。

Sample Input

1
3
2

Sample Output

1
3
2

本题是经典的递推问题,解决递推问题的精华在于分体问题的方法

思路一:

  • 在2 × 1的一个长方形方格中,用一个1 × 2的骨牌铺满方格,只有1种铺法在这里插入图片描述
  • 在2 × 2的一个长方形方格中,用一个1 × 2的骨牌铺满方格,有2种铺法
    在这里插入图片描述
    在这里插入图片描述
  • 在2 × 3的一个长方形方格中,用一个1 × 2的骨牌铺满方格,只有3种铺法(题目中已给出)
  • 在2 × 4的一个长方形方格中,用一个1 × 2的骨牌铺满方格,只有5种铺法… …
  • 综上:设铺满2 x n方格的方法数为F(n),则:
    当n = 1时,方案数F(1) = 1.
    当n = 2时,方案数F(2) = 2.
    当n = 3时,方案数F(3) = 3 = F(1) + F(2)
    当n = 4时,方案数F(4) = 5 = F(2) + F(3)
    … …
    发现规律:
    当n = n时,F(n) = F(n - 1) + F(n - 2)

得出AC代码如下

#include <iostream>

using namespace std;

typedef long long LL;
LL dp[55];//防止越界

int main()
{
    int n;
    
    dp[1] = 1;
    dp[2] = 2;
    
    //打表 + 状态转移方程
    for (int i = 3;i <= 55;i++) dp[i] = dp[i - 1] + dp[i - 2];
    
    while (cin >> n)
    {
        cout << dp[n] << endl;
    }
    return 0;
}

但是,如果题目所给条件比较复杂,无法从前往后推出状态转移方程,那可以考虑从后往前推:

  • 首先,不管总的方案有多少种,对于2行n列的格子,第一行的最后一个格子要么被骨牌竖着盖住,要么被骨牌横着盖住
  • 当第一行的最后一个格子被骨牌竖着盖住时,可以将n列的格子分解为n - 1列格子的覆盖问题——即F(n - 1)种方法,如图所示:在这里插入图片描述
  • 当第一行的最后一个格子被骨牌横着盖住时,第二行的最后一个格子的覆盖方法也随之确定了,故可以将n列的格子分解为n - 2列格子的覆盖问题——即F(n - 2)种方法,如图所示:在这里插入图片描述
  • 综上,仍然可以推出状态转移方程F(n) = F(n - 1) + F(n - 2)

补充例题:

有个1 × n的长方形,用1 × 1、1 × 2、1 × 3的骨牌铺满方格。例如:当n = 3时为1 × 3的方格(如图),此时共有四种铺法。在这里插入图片描述

在这里插入图片描述

  • 若最后一个格子被1 x 1的骨牌铺满,则前面n - 1个格子有F(n - 1)种铺法
  • 若最后一个格子被1 x 2的骨牌铺满,则前面n - 2个格子有F(n - 2)种铺法
  • 若最后一个格子被1 x 3的骨牌铺满,则前面n - 3个格子有F(n - 3)种铺法
  • F(1) = 1
  • F(2) = 2
  • F(3) = 4
  • 故得出状态转移方程:F(n) = F(n - 1) + F(n - 2) + F(n - 3)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值