解析
首先,因为是不同的数字,
可以从小到大依次枚举加上每一个数字的贡献,再枚举每个数.
然而这样会T掉...
考虑到(n)只有(50000),
当分成的数最多时,设最大的数为(m),
则(1+2+3...+m<=n),
所以最多只会分成315个数((m<316)).
那么设(f[j][i])表示把(j)分成(i)个数的方案数.
依次枚举加上的数(i),
那么这个(i)要么作为单独的一块加上去,
要么就分成(i)块给之前的贡献过的每个数加1.
所以转移方程:(f[j][i]-f[j-i][i-1]+f[j-i][i]).
最后(ans=sum_{i=1}^{315}f[n][i]).
code(可能代码里面有一些时候大于了315别在意):
#include <iostream>
#include <cstdio>
#include <cstring>
#define filein(a) freopen(a".cpp","r",stdin)
#define fileout(a) freopen(a".cpp","w",stdout);
using namespace std;
inline int read(){
int sum=0,f=1;char c=getchar();
while((c<'0'||c>'9')&&c!=EOF){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'&&c!=EOF){sum=sum*10+c-'0';c=getchar();}
return sum*f;
}
const int N=50001;
const int Mod=1000000007;
int n,f[N][401];
int main(){
n=read();f[1][1]=1;
for(int i=1;i<=320;i++){
for(int j=i+1;j<=n;j++) f[j][i]=(f[j-i][i]+f[j-i][i-1])%Mod;
}
int ans=0;
for(int i=1;i<=320;i++) ans=(ans+f[n][i])%Mod;
printf("%d
",ans);
return 0;
}