输入
输出
输入样例复制
input 1:
6 25
8 9 8 7 16 5
input 2:
30 250
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
输出样例复制
output 1:
15
output 2:
6509431
说明
题解:设f[i,j]表示处理i~n,用了代价j 的方案数。
将礼物从小到大排序,枚举每一件礼物,强制使该礼物为最小不能买的礼物
则小于该礼物的全部都要强制购买,剩余rest 钱
则对于第i个礼物的答案为sigma(f[i+1,max(0,rest-a[i]+1)~rest]) 即用的钱要使剩下的钱<a[i],且第i个无法购买,所以是i+1
注意初值
const
maxn=1001;
p=10000007;
var
f:array[0..maxn,0..maxn]of longint;
c:array[0..maxn]of longint;
n,m,i,j,min,kk,rest,ans,flag:longint;
procedure qsort(l,r:longint);
var
i,j,key:longint;
begin
if l>r then exit;
i:=l;j:=r;
key:=c[(l+r)div 2];
repeat
while c[i]<key do inc(i);
while c[j]>key do dec(j);
if i<=j then
begin
c[0]:=c[i];c[i]:=c[j];c[j]:=c[0];
inc(i);dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
procedure init;
var
i,sum:longint;
begin
readln(n,m);
sum:=0;
for i:=1 to n do
begin
read(c[i]);
sum:=sum+c[i];
end;
if sum<=m then flag:=1;
qsort(1,n);
f[n,c[n]]:=1;
f[n,0]:=1;
end;
begin
init;
if flag=1 then
begin
writeln(1);
halt;
end;
for i:=n downto 1 do
for j:=0 to m do
begin
if (j>=c[i]) then f[i,j]:=(f[i,j]+f[i+1,j-c[i]])mod p;
f[i,j]:=(f[i,j]+f[i+1,j])mod p;
end;
for kk:=1 to n do
begin
rest:=m;
for i:=1 to kk-1 do
rest:=rest-c[i];
if rest<0 then break;
min:=c[kk];
for i:=max(rest-c[kk]+1,0) to rest do
ans:=(ans+f[kk+1,i])mod p;
end;
writeln(ans);
end.