家庭作業 紀中2549 貪心 優化

2021-07-16 14:58:46 字數 1966 閱讀 8254

老師在開學第一天就把所有作業都布置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。例如如果乙個作業學分為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次作業的學分和完...