题目:给你一个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;
- }