大意略。
思路:
参考了UVA论坛里的思路:
Let f(n) be the number of way to connect the main transmission center (mtc) and n houses. By removing the mtc and its cables to the houses, there will be one or more connected components of houses. Let k be the number of houses of the right most connected component. Then,
1. there are k ways to connect one cable from the mtc to this component, and
2. there are f(n-k) ways to connect the mtc to the rest n-k houses.
So, there are k*f(n-k) to connect them all. Since the range of k is from 1 to n inclusive, by setting f(0)=1, we then have
f(n) = 1*f(n-1) + 2*f(n-2) + ... + (n-1)*f(1) + n*f(0)
fib(2*n) =fib(n+1)*fib(n) + fib(n)*f(n-1) (Fibonacci)
于是化简可以得: f(n) = fib(2*n);
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 1100;
struct bign
{
int s[maxn], len;
bign () { memset(s, 0, sizeof(s)); len = 1;}
bign (int num) { *this = num;}
bign (const char *num) { *this = num;}
bign operator = (const int num)
{
char s[maxn];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bign operator = (const char *num)
{
len = strlen(num);
for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
return *this;
}
bign operator + (const bign &b) const //+
{
bign c;
c.len = 0;
for(int i = 0, g = 0; g || i < max(len, b.len); i++)
{
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % 10;
g = x / 10;
}
return c;
}
void print()
{
for(int i = len-1; i >= 0; i--) printf("%d", s[i]);
printf("\n");
}
}f[4100];
void init()
{
f[1] = f[2] = 1;
for(int i = 2; i <= 4013; i++) f[i] = f[i-1] + f[i-2];
}
int main()
{
int n;
init();
while(scanf("%d", &n) && n)
{
f[2*n].print();
}
return 0;
}