老師在開學第一天就把所有作業都布置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。例如如果乙個作業學分為10,要求在6天內交,那麼要想拿到這10學分,就必須在第6天結束前交。
每個作業的完成時間都是只有一天。例如,假設有7次作業的學分和完成時間如下:
作業號 1 2 3 4 5 6 7
期限 1 1 3 3 2 2 6
學分 6 7 2 1 4 5 1
最多可以獲得15學分,其中乙個完成作業的次序為2,6,3,1,7,5,4,注意可能d還有其他方法。
你的任務就是找到乙個完成作業的順序獲得最大學分。
第一行乙個整數n,表示作業的數量。接下來n行,每行包括兩個整數,第乙個整數表示作業的完成期限,第二個數表示該作業的學分。
輸出乙個整數表示可以獲得的最大學分。保證答案不超過longint範圍。
我們先把作業按學分從大到小排個序。
用陣列f標記第i個時間有沒有用過。
然後從第乙份作業開始選擇做不做。
如果在這乙份作業(作業i)的期限之前還有時間可以空閒(f[i]=0),那就做這乙份作業,並且用乙個陣列標記一下這個時間已經用了(f[i]=1)。
這裡可以用乙個優化,用乙個鍊錶f,f[i]指向f[i]之前的空閒時間,具體見程式
type
arr=record
x,y:longint;
end;
var i,j,k:longint;
f,fa:array[1..1000010] of longint;
a:array[1..1000010] of arr;
n:longint;
ans:longint;
procedure
qsort
(l,r:longint);
var i,j,k:longint;
mid:longint;
temp:arr;
begin
if l>=r then
exit;
i:=l;
j:=r;
mid:=a[(l+r) div
2].y;
repeat
while a[i].y>mid do i:=i+1;
while a[j].ydo j:=j-1;
if i<=j
then
begin
temp:=a[i]; a[i]:=a[j]; a[j]:=temp;
i:=i+1; j:=j-1;
end;
until i>j;
qsort(l,j);
qsort(i,r);
end;
function
find
(x:longint):longint;//優化,更新鍊錶
var i,j,k:longint;
begin
if (x=0) or (f[x]=0) then
exit(x);
fa[x]:=find(fa[x]);
exit(fa[x]);
end;
begin
readln(n);
for i:=1
to n do
readln(a[i].x,a[i].y);
qsort(1,n);
ans:=0;
for i:=2
to n do
fa[i]:=i-1;
for i:=1
to n do
begin
j:=find(a[i].x);
if j<>0
then
begin
f[j]:=1;
ans:=ans+a[i].y;
end;
end;
write(ans);
end.
Jzoj 2549 家庭作業
老師在開學第一天就把所有作業都布置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。每個作業的完成時間都是只有一天 例如,假設有7 77次作業的學分和完成時間如下 第一天第二天 第三天第四天 第五天第六天 第七天作業號12 3456 7期限11 3322 6學分...
貪心 家庭作業
題目描述 老師在開學第一天就把所有作業都布置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。例如如果乙個作業學分為10,要求在6天內交,那麼要想拿到這10學分,就必須在第6天結束前交。每個作業的完成時間都是只有一天。例如,假設有7次作業的學分和完成時間如下 老...
家庭作業 Standard IO
description 老師在開學第一天就把所有作業都布置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。例如如果乙個作業學分為10,要求在6天內交,那麼要想拿到這10學分,就必須在第6天結束前交。每個作業的完成時間都是只有一天。例如,假設有7次作業的學分和完...