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 }

贴上一位大神的代码如下:

 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("\n");
24     }
25     return 0;
26 }


 
时间: 2024-10-09 06:21:31

poj 2506 Tiling(高精度)的相关文章

POJ 2506 -TILING

水题,一个小模拟,规律也好找 f3 = f1 * 2 + f2; #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> const int INF = 1e8; const int N = 100; #define ll long long using namespace std; int a[251][N]

poj 2506 Tiling(java解法)

题目链接:http://poj.org/problem?id=2506 本题用的java解的,因为涉及到大数问题,如果对java中的大数操作不熟悉请点这儿:链接 思路:地推公式f[i]=f[i-1]+2*f[i-2] code: import java.math.*; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin=new Scanner(Syst

[ACM] POJ 2506 Tiling (递推,大数)

Tiling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7487   Accepted: 3661 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,

POJ 2506 Tiling (递推+高精度)

[题目链接]click here~~ [题目大意] In how many ways can you tile a 2xn rectangle by 2x1 or 2x2 tiles? Here is a sample tiling of a 2x17 rectangle. [解题思路]: (1)一个2*2的格子有三种填充方法: 两个横着放, 两个竖着放, 放一个2*2 (2)得出递推公式F[i]=F[i-1]+F[i-2]*2 然后就是套高精度模板了 代码; /* Author:HRW 递推+

POJ 2506 Tiling(高精度+递推)

高精度模版(bin神的) /* * 高精度,支持乘法和加法 */ struct BigInt { const static int mod = 10000; const static int DLEN = 4; int a[600],len; BigInt() { memset(a,0,sizeof(a)); len = 1; } BigInt(int v) { memset(a,0,sizeof(a)); len = 0; do { a[len++] = v%mod; v /= mod; }w

POJ 2506 Tiling(递推+大整数加法)

http://poj.org/problem?id=2506 题意: 思路:递推.a[i]=a[i-1]+2*a[i-2]. 计算的时候是大整数加法.错了好久,忘记考虑1了...晕倒. 1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 7 int n; 8 char s[255][255]; 9 10

poj 2506 Tiling 递推

题目链接: http://poj.org/problem?id=2506 题目描述: 有2*1和2*2两种瓷片,问铺成2*n的图形有多少种方法? 解题思路: 利用递推思想,2*n可以由2*(n-1)的状态加上一块竖放2*1的瓷片转移得来,也可以由2*(n-2)的状态加上一块2*2的瓷片或者加上两块横放的2*1的瓷片转移得来. 可得出递推公式:dp[n] = dp[n-1] + dp[n-2]*2: ac秘诀: (1):从输出样例可以看出要用大数来表示,大概需要90位左右. (2):2*0不是零种

POJ 2506 Tiling (递推 + 大数加法模拟 )

Tiling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7965   Accepted: 3866 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,

[ACM] POJ 2506 Tiling (递归,睑板)

Tiling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7487   Accepted: 3661 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,