题意:给你一个整数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.