51nod 1201

27 篇文章 0 订阅

题意:给你一个整数n(n<=50000),n可以划分为多个整数相加的和,现在要求总方案,但是组成n的整数不能相同。

题解:这题目比较锻炼思维,我一开始n<=50000还以为是O(n)…思维太狭窄了。。因为要求每个整数都不相同。所以我们假设最多需要多少整数,即:1+2+3+…+x
假设n为最大50000,那么x最多也就350左右的样子((1+350)*350/2>50000)所以我们只要找350个左右的整数就够了,这样时间就能保证。
那么接下来怎么找呢?设DP[I,J]表示i由j个数组成的总方案。
然后我们就可以很显然(显然个屁)的得到一个方程:dp[i,j]=dp[i-j,j]+dp[i-j,j-1]什么意思呢?
dp[i-j,j]是所有组成i的数全部-1的方案,dp[i-j,j-1]则是少一个数的方案。
来自Q巨的解释:转移应该是所有数+1 然后 枚举是否放上一个1,这样能保证所有数不同。
贴代码:



const mo=1000000007;
var
        i,j,n,m:longint;
        dp:array[0..50000,0..350]of longint;
function max(x,y:longint):longint;
begin
        if x>y then exit(x)
        else exit(y);
end;
begin
        readln(n);
        dp[0,0]:=1;
        for i:=1 to 349 do
        begin
                for j:=0 to n do
                begin
                        if j-i>=0 then
                        dp[j,i]:=(dp[j-i,i]+dp[j-i,i-1])mod mo;
                end;
        end;
        for i:=1 to 349 do
        m:=(m+dp[n,i])mod mo;
        writeln(m);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值