4 5 11 15 19
7 56 176 490
题意:整数拆分,把n分成若干个数相加的种数。
思路:易知其母函数为:G(x)=(1+x+x^2+...)*(1+x^2+x^4+...)*(1+x^n+...),即:
由五边形定理可以知道G(x)=sigma(P(k)x^k),其中P(n)=P(n-1)+P(n-2)-P(n-5)-P(n-7)+...
http://zh.wikipedia.org/wiki/%E4%BA%94%E9%82%8A%E5%BD%A2%E6%95%B8%E5%AE%9A%E7%90%86
#include <iostream> #include <stdio.h> #include <cmath> #include <algorithm> #include <string.h> #define LL long long #define scan(a) scanf("%d",&a) #define REP(i,a,b) for(int i=a;i<b;++i) #define mset(a,b) memset(a,b,sizeof a) #define mod 1000000007 const int maxn=1e5+10; using namespace std; LL ans[maxn]; inline LL pj(LL j) { LL ret = (3*j*j+j)/2; return ret; } void init() { mset(ans,0); ans[0]=1; REP(i,1,maxn) { for(int j=1;pj(-j)<=i;++j) { int r=(j%2)?1:-1; int a=pj(-j); int b=pj(j); if(a<=i) { ans[i]+=ans[i-a]*r; ans[i]=(ans[i]%mod+mod)%mod; } if(b<=i) { ans[i]+=ans[i-b]*r; ans[i]=(ans[i]%mod+mod)%mod; } } } } int main() { int t; int n; init(); cin>>t; while(t--) { scan(n); printf("%I64d\n",ans[n]); } }