本题参考了解题索引,采用二分:
若知F(1).....F(n) 求F(n+1)
可以将n+1序列中最大的那个数抽调出来,先固定它的位置,然后采用二分法依次求解。
(暂且用n+1来表示最大的那个数) n+1一定在某一组的最后面,设它在的组是第x组(不包含<3的组),则前面的序列有3*x-1,后面有n+1-3*x,故有下列公式:
F(n+1) = F(3*x-1)*F(n+1-3*x)*C(n,3*x-1)
注意当(n+1)%3==2时,还需要加上F(n)
本题中还有一个需要注意的点:
1、数据大小为64位,所以采用了长整型:long long
2、计算C组合时,应简化计算,C(n,k)=n*..(n-k+1)/K! =C(n,n-k)
代码如下:
#include<stdio.h>
#include<iostream>
#define rep(i, n) for (long long i = 1; i <= (n); ++i)
using namespace std;
long long comb(long long n, long long k){
long long a=1, b=1,c=1;
if (k > n - k) k = n - k;
rep(i, k)
a *= n+1-i;
rep(i, k)
b *= i;
return a/b;
}
long long F(long long n){
if (n == 0)
return 1;
if (n >= 0 && n <= 3)
return 1;
long long x = n/ 3;
long long ans = 0;
rep(i, x)
ans += F(3 * i - 1)*F(n - 3 * i)*comb(n - 1, 3 * i - 1);
if (n % 3 == 2)
ans += F(n - 1);
return ans;
}
int main(){
long long nt;
while (cin>>nt)
{
if (!nt)
cout << 0 << endl;
else
{
long long anst = F(nt);
cout << anst << endl;
}
}
}
2279

被折叠的 条评论
为什么被折叠?



