铺地砖

时间限制: 1 Sec  内存限制: 128 MB

题目描述

一天,晨晨的数学老师布置了一道题目,大意如下:用1×1和2×2的磁砖不重叠地铺满n×3的地板,共有多少种方案?
例如:n=1时:1×3的地板方法就一个,直接由三个1×1的磁砖铺满。
      n=2时:2×3的地板可以由下面3种方案铺满:

 

输入

第一行:一个整数n(1≤n≤100)。

 

输出

输出铺满n×3的地板的方案数。

 

样例输入

复制样例数据

3

样例输出

5

 

提示

对于20%的数据,1≤n≤15;
对于50%的数据,1≤n≤30;
对于100%的数据,1≤n≤100;

 

设宽为n的时候方案数为f[n];

根据这张图可以发现,宽为2,长为3的有3种方法。由于长是固定为3的,那么当宽大于2的时候,可以试着找

通过n-1,n-2的宽度来找,去掉n-1行,那么就剩下最后一行,只能铺1*1的砖3块,所以为f[n-1];去掉n-2行,那么还剩下两行,也就只有上面三种方法,是3种吗,看方法三,和去掉n-1行重复了,所以只有2种方法为2*f[n-2];

所以总共f[n]=f[n-1]+2*f[n-2];

由于数据太大,用大数做。

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>

typedef long long LL;
using namespace std;

int f[105][10005];
int n;

void solve(int a[], int b[], int c[]){
	for (int i = 1; i <= b[0]; i++){
		a[i] += 2 * b[i];
		if(a[i] > 9){
			a[i + 1] += a[i] / 10;
			a[i] %= 10;
		}
	}
	int len = b[0];
	while(a[len + 1]) len++;
	for (int i = 1; i <= c[0]; i++){
		a[i] += c[i];
		if(a[i] > 9){
			a[i + 1]++;
			a[i] -= 10;
		}
	}
	int cnt = c[0];
	while(a[cnt + 1]){
		if(a[cnt + 1] > 9){
			a[cnt + 2]++;
			a[cnt + 1] -= 10;
			cnt++;
		}else{
			cnt++;
			break;
		}
	}
	a[0] = max(cnt, len);
}

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);

	scanf("%d", &n);
	f[1][0] = 1, f[1][1] = 1, f[2][0] = 1, f[2][1] = 3;
	for (int i = 3; i <= n; i++){
		solve(f[i], f[i - 2], f[i - 1]);
	}
	for (int i = f[n][0]; i >= 1; i--) printf("%d", f[n][i]);
	printf("\n");

	return 0;
}
/**/