首先审题别出偏差。意思就是一行数据,需要3个3个递增然后分成不同的队伍,最后一个或者两个可以自成一队。不能用简单的组合来写…
思路是使用二分法的递归…
思考f[n]和f[n+1]的关系。第n+1个人(按照身高排序)肯定是在某个队伍中的最后一个的。所以假设包括n+1这个人的队以及这个队之前的队总共有x支,则n+1这个人前面有x*3-1个人. 再考虑这个人之后,则应该有n+1-3*x个人. 那么得到关系式:
f[n+1]=sum(f[x∗3−1]∗f[n+1−3∗x]∗c[n,x∗3−2])
C[n,x*3-2]意思就是n+1个人分成两组的分法, 每种分法前后两组的队伍数都是那两个函数.
然后还要注意的是n+1个人可以在最后一个队为两人或三人的时候成为最后一队的最后一人, 上面的公式累加后已经包含三人的情况, 但是没有包含两人的情况, 所以当(n+1)%3 = 2时最后结果还要加上f(n).
然后再注意…结果很大…in和long都不行, 要用long long…
//
// Created by Frank on 17/12/7.
//
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
using namespace std;
long long combine(long long n, long long k){
long long a =1, b=1;
if(k>n-k) k = n-k;
for(long long i=1;i<=k;i++)
a *= n-i+1;
for(long long i=1;i<=k;i++)
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 result = 0;
for(long long i=1;i<=x;i++)
result += f(i*3-1)*f(n-3*i)*combine(n-1,i*3-1);
if(n%3==2) result += f(n-1);
return result;
}
int problem11(){
long long n;
while(cin>>n){
cout<<f(n)<<endl;
}
}