多多看DVD(加强版)
(watchdvd.pas/c/cpp)
【问题描述】
可是出现了一个奇怪的问题,买碟的地方只买给顾客M(M<N)张碟,不会多也不会少。这可让多多叔叔为难了。怎么可以在N张碟中只买M张而且在规定时间看完,而且使总价值最高呢?
聪明的你帮帮多多的叔叔吧。
【输入说明】(watchdvd.in)
【输出说明】(watchdvd.out)
表示多多今晚看的碟的总分。
如果商店卖给叔叔的M张碟无法在爷爷规定的时间看完输出0;
【输入样例】
【输出样例】
【数据范围】
【时限】
1S
============================
注意无效状态的确定...
=====================
type
re=record
t,m:longint;
end;
var
n,m,l:longint;
a:array[1..100]of re;
f:array[0..100,0..100,0..1000]of longint;
procedure init;
begin
assign(input,'watchdvd.in');
assign(output,'watchdvd.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure qsort(s,t:longint);
var
i,j:longint;
x:longint;
tem:re;
begin
x:=a[(s+t)shr 1].t;
i:=s; j:=t;
repeat
while x<a[j].t do dec(j);
while x>a[i].t do inc(i);
if i<=j then
begin
tem:=a[i];
a[i]:=a[j];
a[j]:=tem;
inc(i); dec(j);
end;
until i>j;
if i<t then qsort(i,t);
if s<j then qsort(s,j);
end;
procedure main;
var
i,j,k:longint;
ans:longint;
begin
readln(n,m,l);
for i:=1 to n do read(a[i].t,a[i].m);
qsort(1,n);
ans:=0;
for i:=1 to m do ans:=ans+a[i].t;
if ans>l then
begin
writeln(0);
terminate;
end;
fillchar(f,sizeof(f),0);
for i:=1 to n do
for j:=1 to m do
for k:=0 to l do
begin
f[i,j,k]:=f[i-1,j,k];
if k>=a[i].t then
if (f[i-1,j-1,k-a[i].t]<>0)or((j=1)and(k=a[i].t)) then
if f[i,j,k]<f[i-1,j-1,k-a[i].t]+a[i].m then
f[i,j,k]:=f[i-1,j-1,k-a[i].t]+a[i].m;
end;
ans:=-maxlongint;
for i:=0 to l do
if ans<f[n,m,i] then ans:=f[n,m,i];
writeln(ans);
//writeln(f[n,m,l]);
end;
begin
init;
main;
terminate;
end.