题意:求0/1背包的前K优解总和
k<=50 v<=5000 n<=200
思路:日常刷水
归并即可,不用排序
1 const oo=800000000; 2 var dp:array[0..1,0..5000,1..50]of longint; 3 w,c,a,b:array[1..200]of longint; 4 n,m,k1,i,j,k,x,y,ans,v:longint; 5 6 begin 7 assign(input,'data.in'); reset(input); 8 assign(output,'Tyvj1412.out'); rewrite(output); 9 readln(k1,m,n); 10 for i:=1 to n do read(w[i],c[i]); 11 fillchar(dp[v],sizeof(dp[v]),$cf); 12 dp[0,0,1]:=0; 13 for i:=1 to n do 14 begin 15 v:=1-v; dp[v]:=dp[1-v]; 16 dp[v,0,1]:=0; 17 for j:=w[i] to m do 18 begin 19 for k:=1 to k1 do a[k]:=dp[1-v,j,k]; 20 for k:=1 to k1 do b[k]:=dp[1-v,j-w[i],k]+c[i]; 21 x:=1; y:=1; 22 for k:=1 to k1 do 23 begin 24 if (a[x]<0)and(b[y]<0) then begin dp[v,j,k]:=-oo; continue; end; 25 if a[x]>b[y] then begin dp[v,j,k]:=a[x]; inc(x); end 26 else begin dp[v,j,k]:=b[y]; inc(y); end; 27 end; 28 end; 29 end; 30 for i:=1 to k1 do 31 if dp[v,m,i]>=0 then ans:=ans+dp[v,m,i] 32 else break; 33 writeln(ans); 34 close(input); 35 close(output); 36 end.