1. 程式人生 > >poj2506 Tiling

poj2506 Tiling

發現 AC pre ima tr1 AR 求解 clas add

http://poj.org/problem?id=2506

題目大意:用多少種方法可以用2*1或2*2瓦片來鋪一個2*n的矩形?

這是一個2*17長方形的樣品。

技術分享圖片

輸入是一行行的序列,每一行包含一個整數0 <= n <= 250。對於每一行輸入,在單獨的行中輸出一個整數,給出一個2 * n矩形的可能擺放方式數。

也就是說給一個2*n的棋盤,用三種方塊(2*2,1*2,2*1)將其鋪滿,求有多少種可能性,通過給出的案例可以發現,輸出的結果很大long long類型也存不下,所以要運用大整數的加法。作圖可以發現遞歸方程式,對2 * 1,2 * 2,2 * 3來說 2 * 1有1種;2 * 2有3種;2 * 3 可以在2 * 2 的基礎上加一個2 * 1豎著放的瓦片,在 2 * 1 的基礎上加一個2 * 2的瓦片,也可以加兩個2 * 1橫著放的瓦片(豎著放與在 2 * 2的基礎上重復)。num[3] = num[2]+ 2 * num[1]

算法思想:遞歸求解,這裏采用一次性計算的叠代法提高算法的效率。我們可以發現遞歸的方程式:

1)num[i] = num[i - 1]+ 2 * num[i - 2]; i>2

2)num[0] = 1 ; i=0

3)num[1] = 1 ; i=1

4)num[2] = 3 ; i=2

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 string Add(string str1, string str2)//大整數加法(兩個正整數)
 5 {
 6     string
str; 7 int len1 = str1.length(); 8 int len2 = str2.length(); 9 if (len1 < len2) //前面補0,使兩個字符串長度相同 10 { 11 for (int i = 1; i <= len2 - len1; i++) 12 str1 = "0" + str1; 13 } 14 else 15 { 16 for (int i = 1; i <= len1 - len2; i++) 17 str2 = "
0" + str2; 18 } 19 len1 = str1.length(); 20 int cf = 0;//進位 21 int temp;//當前位的值 22 for (int i = len1 - 1; i >= 0; i--) 23 { 24 temp = str1[i] - 0 + str2[i] - 0 + cf; 25 cf = temp / 10; 26 temp %= 10; 27 str = char(temp + 0) + str; 28 } 29 if (cf != 0) str = char(cf + 0) + str; 30 return str; 31 } 32 int main() 33 { 34 string num[251] = { "1","1","3" }; 35 for (int i = 3; i <= 250; i++) 36 { 37 num[i] = Add(num[i - 1], Add(num[i - 2], num[i-2])); 38 } 39 int temp; 40 while (cin >> temp) { 41 cout << num[temp] << endl; 42 } 43 return 0; 44 }

poj2506 Tiling