51nod-1201: 整数划分
【传送门:51nod-1201】
简要题意:
给出一个整数n,将N分为若干个不同整数的和,求有多少种不同的划分方式
题解:
DP
设f[i][j]表示用i个数组成j的方案数,因为n<=50000,而且划分出来的数要不同,所以最多只能分成320(还要小一点)个数的和,所以i最大为320
转移=f[i][j-i]+f[i-1][j-i]
前者表示j分成的i个数中不包括1的方案数(因为将j-i相当于将i个数都-1,自然一开始就不可能有1)
后者表示j分为的i个数中包括1的方案数(因为原本有1,所以-1之后就变成了i-1个数了)
这转移卡了一会,有点菜。。
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; int f[410][51000],Mod=1e9+7; int main() { int n; scanf("%d",&n); memset(f,0,sizeof(f)); f[0][0]=1; for(int i=1;i<=320;i++) { for(int j=i;j<=n;j++) { f[i][j]=((LL)f[i-1][j-i]+(LL)f[i][j-i])%Mod; } } int ans=0; for(int i=1;i<=320;i++) ans=((LL)ans+(LL)f[i][n])%Mod; printf("%d\n",ans); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚