题目:给你一个2*n的地面,用1*2和2*2的地板砖铺满,有多少种不同方案。
分析:组合数学,动态规划。直接找到地推关系求解。
因为,只可能是最后一列是一个整体(1种情况)或者最后两列是一个整体(两种情况);
所以,有递推公式:f(n)= f(n-1)+ 2*f(n-2);
可以使用动态规划或母函数(an = (pow(2,n+1)-pow(-1,n+1))/ 3)求解。
说明:大整数运算,这里采用dp求解,貌似快速幂会快点╮(╯▽╰)╭。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int ans[255][101],two[101];
void copy_array(int *a, int *b)
{
for (int i = 0; i < 100; ++ i)
a[i] = b[i];
}
void add_array(int *c, int *a, int *b)
{
for (int i = 0; i < 100; ++ i)
c[i] = 0;
for (int i = 0; i < 100; ++ i) {
c[i] += a[i]+b[i];
if (c[i] > 9) {
c[i+1] += c[i]/10;
c[i] %= 10;
}
}
}
void output_array(int *a)
{
int end = 100;
while (end && !a[end]) -- end;
while (end >= 0) printf("%d",a[end --]);
printf("\n");
}
int main()
{
memset(ans, 0, sizeof(ans));
ans[0][0] = 1;ans[1][0] = 1;
for (int i = 2; i < 252; ++ i) {
add_array(two, ans[i-2], ans[i-2]);
add_array(ans[i], ans[i-1], two);
}
int n;
while (~scanf("%d",&n))
output_array(ans[n]);
return 0;
}