• poj 2506 Tiling(高精度)


    Description

    In how many ways can you tile a 2xn rectangle by 2x1 or 2x2 tiles? 
    Here is a sample tiling of a 2x17 rectangle. 

    Input

    Input is a sequence of lines, each line containing an integer number 0 <= n <= 250.

    Output

    For each line of input, output one integer number in a separate line giving the number of possible tilings of a 2xn rectangle. 

    Sample Input

    2
    8
    12
    100
    200

    Sample Output

    3
    171
    2731
    845100400152152934331135470251
    1071292029505993517027974728227441735014801995855195223534251

    刚开始没推出来,还是看了Discuss才知道递推公式是:f[n]=f[n-1]+2*f[n-2],推论方法如下:
    首先,无论任何一种方案,最左边的要么是一根竖的,要么是两根横的,要么是一个方的,对吧?所以:
    当是一根竖时剩下的方案数是OPT[i-1]
    当是两根横时剩下的方案数是OPT[i-2]
    当是一个方时剩下的方案数是OPT[i-2]
    故OPT[i]=OPT[i-1]+2*OPT[i-2]
    转化为二阶齐次常系数线性方程为:
    f(n-2)-f(n-1)-2f(n-2)=0
    其特征方程是:
    x^2-x-2=0
    解得特征方程的根式:x=-1 或 x=2
    故得
    f(n)=a*(-1)^n+b*2^n
    将f(0)=1,f(1)=1的值代入,解得f(n)=1/3*(-1)^n+2/3*2^n
    可简化为:
    if(n%2==0)
    opt[n]=(2^(n+1)+1)/3
    else
    opt[n]=(2^(n+1)-1)/3
    不要问我为什么,我也不知道。然后尝试着自己写,于是乎就把自己绕进去了,看了大神的代码才知道什么叫巧妙。。。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 using namespace std;
     5 struct pos
     6 {
     7     int a[1500];
     8     int len;
     9 } path[300];
    10 void c2(pos &x)    //乘2操作
    11 {
    12     int len=x.len;
    13     for(int i=1; i<=len; i++)
    14         x.a[i]*=2;
    15     for(int i=1; i<=len; i++)
    16     {
    17         if(x.a[i]>9)
    18         {
    19             x.a[i]-=10;
    20             x.a[i+1]++;
    21         }
    22     }
    23     if(x.a[len+1]!=0)
    24         x.len++;
    25 }
    26 void add(pos &a,pos b,pos c)/*加操作*/
    27 {
    28     int Max=max(b.len,c.len);
    29     for(int i=1; i<=Max; i++)
    30         a.a[i]=b.a[i]+c.a[i];
    31     for(int i=1; i<=Max; i++)
    32     {
    33         if(a.a[i]>9)
    34         {
    35             a.a[i]-=10;
    36             a.a[i+1]++;
    37         }
    38     }
    39     if(a.a[Max+1]!=0)
    40         a.len=Max+1;
    41     else
    42         a.len=Max;
    43 }
    44 int main()
    45 {
    46     int n;
    47     while(cin>>n)
    48     {
    49         memset(path,0,sizeof(path));
    50         path[0].a[1]=1;
    51         path[1].a[1]=1;
    52         path[0].len=path[1].len=1;
    53         for(int i=2; i<=n; i++)
    54         {
    55             c2(path[i-2]);
    56             add(path[i],path[i-1],path[i-2]);
    57         }
    58         for(int i=path[n].len; i>=1; i--)
    59             cout<<path[n].a[i];
    60         cout<<endl;
    61     }
    62     return 0;
    63 }
    View Code
    贴上一位大神的代码如下:

     1 #include <iostream>
     2 #define base 100000000
     3 int a[251][12];
     4 int main(int argc, char** argv) {
     5     a[0][0]=a[1][0]=1;
     6     for(int i=2;i<=250;i++){
     7         for(int j=0;a[i-1][j];j++){
     8             a[i][j]+=a[i-1][j]+2*a[i-2][j];
     9             if(a[i][j]>=base){
    10             a[i][j+1]+=a[i][j]/base; 
    11             a[i][j]%=base; 
    12             }
    13         }
    14     }
    15     int n;
    16     while(~scanf("%d",&n)){
    17         int j;
    18         for(j=0;a[n][j];j++);
    19         j--;
    20         printf("%d",a[n][j--]);
    21         while(j>=0)
    22         printf("%08d",a[n][j--]);
    23         printf("
    ");
    24     }
    25     return 0;
    26 }
    View Code
    
    
    
     
  • 相关阅读:
    Codeforces Round #325D (Div. 2) (DP)
    Codeforces Round #382 (Div. 2) (模拟|数学)
    HDU5950-Recursive sequence(矩阵快速幂)
    9. javacript高级程序设计-客户端检测
    8. javacript高级程序设计-BOM
    7. javacript高级程序设计- 函数表达式
    6. javacript高级程序设计-面向对象设计
    Js注释
    5. javacript高级程序设计-引用类型
    4. javacript高级程序设计-变量、作用域和内存问题
  • 原文地址:https://www.cnblogs.com/cxbky/p/4869393.html
Copyright © 2020-2023  润新知