In how many ways can you tile a 2 × n rectangle by 2 × 1 or 2 × 2 tiles?
Here is a sample tiling of a 2 × 17 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 2 × n rectangle.
Sample Input
2
8
12
100
200
Sample Output
3
171
2731
845100400152152934331135470251
1071292029505993517027974728227441735014801995855195223534251
题链接:UVA10359 Tiling
问题简述:(略)
问题分析:
这个问题的关键是数列的递推式,同时需要注意起始项的值。递推式如下:
f0=1
f1=1
......
fn=2*fn-2 + fn-1。
大数计算是用模拟法来实现的,参见程序。
程序说明:
用Java程序来完成大数计算是最为方便的。
题记:(略)
参考链接:(略)
AC的C++语言程序如下:
AC的C++语言程序(模拟法)如下:
/* UVA10359 Tiling */
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long LL;
const int N = 250;
const int N2 = N / 17;
const LL BASE = 1e17;
LL fib[N + 1][N2 + 1];
void setfib()
{
fib[0][0] = 1;
fib[1][0] = 1;
int len = 1;
for(int i = 2; i <= N; i++) {
int carry = 0;
for(int j = 0; j < len; j++) {
fib[i][j] = 2 * fib[i - 2][j] + fib[i - 1][j] + carry;
carry = fib[i][j] / BASE;
fib[i][j] %= BASE;
}
if(carry)
fib[i][len++] = carry;
}
}
int main()
{
memset(fib, 0, sizeof(fib));
setfib();
int n;
while(~scanf("%d", &n)) {
int k = N2;
while(fib[n][k] == 0)
k--;
printf("%lld", fib[n][k]);
for(int i = k - 1; i >= 0; i--)
printf("%017lld", fib[n][i]);
printf("\n");
}
return 0;
}
AC的Java语言程序如下: