Codevs P3007 智力大冲浪
题目描述 Description
小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。先不要太高兴!因为这些钱还不一定都是你的。接下来主持人宣布了比赛规则: 首先,比赛时间分为n个时段(n≤500),它又给出了很多小游戏,每个小游戏都必须在规定期限ti前完成(1≤ti≤n)。如果一个游戏没能在规定期限前完成,则要从奖励费m元中扣去一部分钱wi,wi为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱! 注意:比赛绝对不会让参赛者赔钱!
输入输出 Input&Output
输入描述 Input Description
输入共4行。
第一行为m,表示一开始奖励给每位参赛者的钱;
第二行为n,表示有n个小游戏; 第三行有n个数,分别表示游戏1~n的规定完成期限;
第四行有n个数,分别表示游戏1~n不能在规定期限前完成的扣款数。
输出描述 Output Description
仅1行。表示小伟能赢取最多的钱。
样例 Sample
样例输入 Sample Input
10000
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
样例输出 Sample Output
9950
数据范围及提示 Data Size & Hint
n≤500
1≤ti≤n
分析
该题采用贪心策略,首先扣钱多的肯定要玩,否侧会使剩下的钱数减少,所以按照代价排序,代价大的排在前,肯定要在自己的最后期限玩,可以为其它游戏让出时间,然后再开始从前往后扫,因为是按代价大的在前排序,所以能玩就玩,在最后期限不能玩就向前扫,找到任何一个时间可以玩就玩,如果找不到任何一个时间来玩游戏,那就让这个游戏排到最后,因为,在任何时间扣钱是一样的,排在最后可以为其他游戏让出时间。
代码如下
program p3007;
type rec=record
t,v:longint;
end;
var m,n,i,j:longint;
game:array[1..500] of rec;
can:array[1..500] of boolean;
head,rear:longint;
flag:boolean;
procedure qsort(l,r:longint);
var i,j,mid:longint;
temp:rec;
begin
i:=l;
j:=r;
mid:=game[(i+j)>>1].v;
while i<=j do
begin
while game[i].v>mid do inc(i);
while game[j].v<mid do dec(j);
if i<=j
then
begin
temp:=game[i];
game[i]:=game[j];
game[j]:=temp;
inc(i);
dec(j);
end;
end;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
begin
readln(m);
readln(n);
for i:=1 to n do
read(game[i].t);
for i:=1 to n do
read(game[i].v);
qsort(1,n);
rear:=n;
fillchar(can,sizeof(can),true);
for i:=1 to n do
begin
if can[game[i].t]
then
begin
can[game[i].t]:=false;
end
else
begin
flag:=false;
for j:=game[i].t downto 1 do
begin
if can[j]
then
begin
can[j]:=false;
flag:=true;
break;
end;
end;
if not flag then
begin
m:=m-game[i].v;
can[rear]:=false;
rear:=rear-1;
end;
end;
end;
write(m);
end.