整数划分有个用五边形数定理
O(nn−−√)
O
(
n
n
)
的做法,粘发链接跑
传送门
code:
#include<set>
#include<map>
#include<deque>
#include<queue>
#include<stack>
#include<cmath>
#include<ctime>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<complex>
#include<iostream>
#include<algorithm>
#define ll long long
#define pb push_back
using namespace std;
const int maxn = 51000;
const int mod = 1e9+7;
int n,m;
int f[maxn],g[maxn];
int main()
{
//freopen("tmp.in","r",stdin);
//freopen("tmp.out","w",stdout);
scanf("%d",&n);
m=0;
for(int i=1;g[m]<=n;i++)
{
g[++m]=i*(3*i-1)/2;
g[++m]=i*(3*i+1)/2;
}
f[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;g[j]<=i;j++)
{
int sig=(j-1>>1&1)?-1:1;
(f[i]+=sig*f[i-g[j]])%=mod;
}
(f[i]+=mod)%=mod;
}
printf("%d\n",f[n]);
return 0;
}