算法:DP
还是用经典的01背包实现,只不过这次f[j,0]表示容量为j时的最大价值,这样的话我们就能统计出一共有多少种方案来了,然后将这些方案的值排序(因为题目中已明确表明不超过20W种,因此快排能够解决),输出结束。
program P1422;
const
maxv=1000;
maxn=2000;
maxzt=200000;
var
m,n,k,tot:longint;
c,v:array [0..maxn] of longint;
f:array [0..maxv,0..maxn] of longint;
s:array [0..maxzt] of longint;
procedure init;
var
i:longint;
begin
readln(m,n);
for i:=1 to n do readln(c[i],v[i]);
readln(k);
end;
procedure main;
var
i,j,l:longint;
begin
for i:=1 to n do
begin
for j:=m downto 0 do
begin
if j=0 then
begin
inc(f[j+c[i],0]);
f[j+c[i],f[j+c[i],0]]:=v[i];
end
else if f[j,0]<>0 then
begin
for l:=1 to f[j,0] do
begin
inc(f[j+c[i],0]);
f[j+c[i],f[j+c[i],0]]:=f[j,l]+v[i];
end;
end;
end;
end;
for i:=m downto 1 do
begin
for j:=1 to f[i,0] do
begin
inc(tot);
s[tot]:=f[i,j];
end;
end;
end;
procedure qsort(l,r:longint);
var
i,j,m,t:longint;
begin
i:=l;
j:=r;
m:=s[(l+r) shr 1];
repeat
while s[i]>m do inc(i);
while s[j]<m do dec(j);
if i<=j then
begin
t:=s[i];
s[i]:=s[j];
s[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure outit;
begin
writeln(tot);
if (k<=tot) and (s[k]<>0) then writeln(s[k]) else writeln('Are You Crazy?');
end;
begin
assign(input,'P1422.in'); reset(input);
assign(output,'P1422.out'); rewrite(output);
init;
main;
qsort(1,tot);
outit;
close(input); close(output);
end.