骨牌铺方格(递推)
作者:互联网
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)
标签:格子,长方形,铺满,方格,骨牌,铺法,递推 来源: https://blog.csdn.net/smallrain6/article/details/113814392