【51Nod 1201】 整数划分

来源:互联网 发布:上古卷轴5男捏脸数据 编辑:程序博客网 时间:2024/05/18 18:56

Description

将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2,3},共4种。由于数据较大,输出Mod 10^9 + 7的结果即可。

Solution

这是一道非常神奇的DP题,用背包直接做会超时。
不过这个DP方程式其实是我推二维背包的时候不小心打错的时候推出来的。
我们设f[i][j]表示用i个数推出j的方案数。
然后f[i][j]=f[i1][ji]+f[i][ji]
表示可以从i-1的一个状态加进来一个i或者把前面的一个状态全部加上1。
那么答案就等于f[i][n]
我们考虑一下所有的情况,全部减一个1或者减去一个i都是可以推到0状态的,所以不遗漏。而且从这个状态往前是没有重复的,所以这个是合法的。

Code

#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef long long ll;const int maxn=50007,mo=1e9+7;ll i,j,k,l,t,n,m,ans;ll f[321][maxn];int main(){    scanf("%d",&n);    f[0][0]=1;    fo(i,1,320){        fo(j,i,n){            f[i][j]=(f[i][j-i]+f[i-1][j-i])%mo;        }    }    fo(i,1,320)ans=(ans+f[i][n])%mo;    printf("%lld\n",ans);}
1 0
原创粉丝点击