UVa 10359 - Tiling

来源:互联网 发布:软件测试流生命周期 编辑:程序博客网 时间:2024/05/17 22:51

题目:给你一个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求解,貌似快速幂会快点╮(╯▽╰)╭。

[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <algorithm>  
  2. #include <iostream>  
  3. #include <cstdlib>  
  4. #include <cstring>  
  5. #include <cstdio>  
  6. #include <cmath>  
  7.   
  8. using namespace std;  
  9.   
  10. int ans[255][101],two[101];  
  11.   
  12. void copy_array(int *a, int *b)  
  13. {  
  14.     for (int i = 0; i < 100; ++ i)  
  15.         a[i] = b[i];  
  16. }  
  17.   
  18. void add_array(int *c, int *a, int *b)  
  19. {  
  20.     for (int i = 0; i < 100; ++ i)  
  21.         c[i] = 0;  
  22.     for (int i = 0; i < 100; ++ i) {  
  23.         c[i] += a[i]+b[i];  
  24.         if (c[i] > 9) {  
  25.             c[i+1] += c[i]/10;  
  26.             c[i] %= 10;   
  27.         }  
  28.     }  
  29. }  
  30.   
  31. void output_array(int *a)  
  32. {  
  33.     int end = 100;  
  34.     while (end && !a[end]) -- end;  
  35.     while (end >= 0) printf("%d",a[end --]);  
  36.     printf("\n");  
  37. }  
  38.   
  39. int main()  
  40. {  
  41.     memset(ans, 0, sizeof(ans));  
  42.     ans[0][0] = 1;ans[1][0] = 1;  
  43.     for (int i = 2; i < 252; ++ i) {  
  44.         add_array(two, ans[i-2], ans[i-2]);  
  45.         add_array(ans[i], ans[i-1], two);  
  46.     }  
  47.       
  48.     int n;  
  49.     while (~scanf("%d",&n))  
  50.         output_array(ans[n]);  
  51.       
  52.     return 0;  
  53. }  
0 0
原创粉丝点击