sicily1121 Tri Tiling

题目链接:http://soj.sysu.edu.cn/1121

题目大意:求用 2 * 1 的矩形拼成 3 * n(0 <= n <= 30)的矩形的方案数。下图是一个3 * 12的实例


解题思路:动态规划。首先根据题意我们可以知道,当 n 为奇数时,3 * n为奇数,即所得的矩形面积为奇数,而用 k 个小矩形拼凑而成的矩形所得面积为 2 * 1 * k,是偶数,故当n为奇数时,是无法找到这样的构造方案的,即其方案数为 0。接下来考虑偶数的情况,当 n = 2 时,共有三种情况,如下图

图1

假设用f(n)表示大矩形另一边长为 n 时总共的方案数。

当 n = 4时,其可以有左边的3*2矩形和右边的3 * 2矩形组成,那么共有 3 * 3 = 9中情况,但是还有哦其他两种情况,如下图,故当n = 4时,其总共有11种情况。

图2

当n = 6时,其可以(1)由左边的 3 * 4矩形和右边的3 * 2矩形组成,此时有f(4) * f(2) = 11 * 3  = 33,但是,这只是对矩形的一种划分,当把矩形划分为(2)左边3 * 2右边3 * 4时,对右边而言,其相比(1)的情况,只是多了图2 的两种情况,因此此时有 f(2) * 2 = 3 * 2 = 6种情况。此外,还可以把矩形作为一个大整体,则又有图3两种情况。因此当n = 6时,其总共有 f(4) * f(2) + f(2) * 2 + 2 = 33 + 6 + 2 = 41种情况

图3

依次类推,当求n时,可以依次把矩形划分为 (1)3 * (n - 2)和 3 * 2的矩形,(2)3 * (n - 4)和3 * 4 的矩形,(3)3 * (n - 6)和 3 * 6 的矩形,······和一个大整矩形

然后对每种情况求解相对前面几种划分没有出现的新增的方案数,即(1)f(n - 2)  * f(2), (2)f(n - 4) * 2(因为这种分法相对(1)的分法右边的矩形只是新增了两种,而左边的矩形可以f(n - 4)种,根据乘法定理,可知新增了 f(n - 4) * 2种方案),(3)f(n - 6) * 2,······,2。然后依次把这些数相加即可得到总的方案数。

用动态转移方程就是:f(n) = f(n - 2) * f(2) + f(n - 4) * 2 + f(n - 6) * 2 + f(n - 8) * 2 +... + f(2) * 2 + 2

至此,本题基本可以求解了,只是有一种情况需要注意,就是当n = 0时,输出应该是 1 而不是 0,至于为什么我至今也没想明白,哪天想明白了再回来补充。

#include <iostream>
using namespace std;

int main()
{
	int dp[35], n;
	while (1)
	{
		cin >> n;
		if (n == -1)
			break;
		if (n % 2 == 1)
		{
			cout << "0" << endl;
			continue;
		}
		dp[0] = 1;
		dp[2] = 3;
		for (int i = 4; i <= n; i += 2)
		{
			dp[i] = dp[i - 2] * dp[2];
			for (int j = i - 4; j >= 0; j -= 2)
				dp[i] += dp[j] * 2;
		}
		cout << dp[n] << endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值