题目:给你一个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; }
时间: 2024-10-19 23:25:39