1. 程式人生 > >AlvinZH的學霸養成記II——1032

AlvinZH的學霸養成記II——1032

AlvinZH的學霸養成記II

時間限制:1000ms   記憶體限制:65536kb

 

題目描述

由於校賽簽到題而遲到的養成記II,你注意到了嗎?

AlvinZH妄圖成為一個學霸,他想學很多很多的課。

教務網上的課都太固定了,AlvinZH準備去慕課上選幾門課學習提高一下姿勢。每門課程依然有持續時間 dd ,雖然沒有固定開始時間,卻有結課時間 ee ,過了DDL後不可再學習此課程。AlvinZH只有在連續學習完一門課後,才會開始下一門課的學習,AlvinZH必須得在結課之前完成每門課的學習。

AlvinZH想知道他最多能學習多少門課,你來幫幫他吧!

注:AlvinZH最早可以從第一天開始學習,結課時間e代表將在第e天結課。

輸入

輸入包含多組資料。

每組資料第一行為課程數n(0<n≤10^5)。

接下來n行,每行兩個整數d和e,代表課程持續時間和結課DDL(0<d,e≤10^6)。

輸出

對於每組資料,輸出一行,為AlvinZH最多可學習的課程數。

輸入樣例

3
1 1
2 2
3 3

輸出樣例

1

HINT

你想到優先隊列了嗎?

HINT2

可參考Leetcode 630. Course Schedule III

題目分析

  1. 考慮到這裡有分別的結束限制,很直觀想法是結束時間靠前的先處理。所以,按照DDL排序,按序處理每門課。
  2. 這時候考慮,某個結束時間靠前的在某個DDL之前放可能是憂的,但是他可能影響DDL靠後的課程的放置導致之後不優。但是,對於當前處理的DDL,顯然放置的科目都是DDL更靠前的。所以刪除之前的課並不影響結果。
  3. 思考到這步結果就出來了,對於某個課的DDL,假設前一個的最多放置方案用了Tot的時間,當前課需要c,如果Tot+c<=DDL則直接放置,否則選出曾經放置的時間最長的課,對比當前的課:如果當前課的代價小,則刪除選出的課,放進當前的課;否則不變。二叉堆維護即可。

具體思路

貪心+優先佇列優化
設定st為當前時間
按結束時間e排序,依次選擇,並將持續時間d入隊,更新st,若st>e則說明無法安排這門課,但此時不是將該門課出隊,而是將佇列內d最長的課出隊(易知能保證出隊後st<e,且能使st更小,因此這樣做是合理的).

出現的問題:一開始優先佇列的型別建的結構體的,覺得邏輯和實現都沒問題,但就一直WA。換了一種寫法,用int的優先佇列就過了。然而兩種寫法貪心部分的邏輯是一樣的,初步判定問題在於sort或優先佇列的實現上,最後發現sort時比較的是結構體的e參量,而優先佇列中比較的是d參量,wa的程式碼只用e的關係過載了結構體的<符,增加了cmp後過了

AC程式碼

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<queue>
 5 using namespace std;
 6 struct Lesson{
 7     int d,e;
 8     bool operator < (const Lesson &a) const{        //過載<,l1<l2為真當且僅當l1.e<l2.e,此時優先佇列生成最大堆
 9         return d<a.d;
10     }
11 };
12 bool cmp(Lesson l1,Lesson l2){
13     return l1.e<l2.e;
14 }
15 const int maxn=100007;
16 priority_queue<Lesson> q;
17 Lesson l[maxn];
18 int main(){
19     int n;
20     while(~scanf("%d",&n)){
21         int st=0;
22         for(int i=0;i<n;++i){
23             scanf("%d%d",&l[i].d,&l[i].e);
24         }
25         sort(l,l+n,cmp);
26         while(!q.empty()) q.pop();
27         for(int i=0;i<n;++i){
28             st+=l[i].d;
29             q.push(l[i]);
30             if(st>l[i].e){
31                 st-=q.top().d;
32                 q.pop();
33             }
34         }
35         printf("%d\n",q.size());
36     }
37 }