【貪心】家庭作業(連結串列優化)
阿新 • • 發佈:2018-12-24
問題 I: 【貪心】家庭作業
時間限制: 1 Sec 記憶體限制: 128 MB
提交: 4 解決: 2
[提交] [狀態] [討論版] [命題人:admin]
題目描述
老師在開學第一天就把所有作業都佈置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。例如如果一個作業學分為10,要求在6天內交,那麼要想拿到這10學分,就必須在第6天結束前交。
每個作業的完成時間都是隻有一天。例如,假設有7次作業的學分和完成時間如下:
老師在開學第一天就把所有作業都佈置了,每個作業如果在規定的時間內交上來的話才有學分。每個作業的截止日期和學分可能是不同的。例如如果一個作業學分為10,要求在6天內交,那麼要想拿到這10學分,就必須在第6天結束前交。
每個作業的完成時間都是隻有一天。例如,假設有7次作業的學分和完成時間如下:
輸入
第一行一個整數N,表示作業的數量;
接下來N行,每行包括兩個整數,第一個整數表示作業的完成期限,第二個數表示該作業的學分。
輸出
輸出一個整數表示可以獲得的最大學分。保證答案不超過C/C++的int範圍。
樣例輸入
7
1 6
1 7
3 2
3 1
2 4
2 5
6 1
樣例輸出
15
提示
對於20%的資料,N≤103;
對於40%的資料,N≤104;
對於60%的資料,N≤105;
對於100%的資料,N≤106,作業的完成期限均小於7×105
【分析】
將作業按分數降序,同分按時限降序。
對每一天構造一個指標,初始時,i指向i-1,當安排第一個作業時,儘量靠後安排,因此在該作業時限之前找一個空閒的天安排上。同時更新指標,使得所有天的指標總是指向前面最靠近的空閒的天。
【程式碼】
#include<bits/stdc++.h> using namespace std; struct PII{ int score,day; }p[1010101]; bool cmp(PII a,PII b) { if(a.score==b.score)return a.day>b.day; return a.score>b.score; } int n; int pre[1010101]; bool vis[1010100]; int father(int day) { if(!vis[day]) return day; return pre[day]=father(pre[day]); } int main() { scanf("%d",&n); for(int i=0;i<n;i++)scanf("%d%d",&p[i].day,&p[i].score); sort(p,p+n,cmp); for(int i=1;i<=700000;i++)pre[i]=i-1,vis[i]=false; int ans=0; for(int i=0;i<n;i++) { int ok=father(p[i].day); if(ok==0)continue; vis[ok]=true; ans+=p[i].score; } printf("%d\n",ans); }