2017年8月8日提高組T1 作業

Description

小A作爲一個乖乖好學生,回到家後總是一絲不苟地完成老師佈置的作業。
這天,老師給小A佈置了n項作業,每一項作業都有截止時間di和價值vi(你可以理解成每做完一份作業就要快遞過去給老師,且快遞是不耗費時間的),每完成一項作業便可獲得其價值。但小A發現,自己每一個單位時間內只能完成其中的一項作業,請你告訴小A,他最多可以獲得多少價值。

Input

第一行有一個正整數n,表示作業的數量。
接下來n行,每行兩個正整數表示di和vi。

Output

輸出一行,表示小A最多可以獲得的價值。

Sample Input

5
1 9
7 6
8 8
1 8
8 6

Sample Output

29
Hint

【樣例說明】

考慮第三組數據,因爲只有一個項目所以只好每天都安排這個。
小A第一天完成第一項作業,第二天完成第二項作業,第三天完成第3項作業,第四天完成第5項作業。

【數據規模與約定】

對於前30%的數據,n<=100.
對於前60%的數據,n<=1000,di<=n
對於100%的數據,n<=100000,di,vi<=1000000000.

思路

其實有至少兩個方法:(1)先按價值來排序,然後每個作業都放在最靠近截止日期的天來放就好
(2)用一個大根堆來維護,每次取堆頂就好了

代碼

#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>

#define N 100005
#define LL long long

using namespace std;

priority_queue<LL, vector<LL>, less<LL> > p;

struct NOTE{
    LL a,b;
}a[N];

LL cmp(NOTE a, NOTE b)
{
    return a.a > b.a;
}

int main()
{
    int n;
    scanf("%d" ,&n);
    for (LL i=1;i <=n;i++)
    {
        scanf("%lld%lld" ,&a[i].a,&a[i].b);
    }
    sort(a+1,a+n+1,cmp);
    LL ans = 0;
    for (int i=1;i<=n;i++)
    {
        p.push(a[i].b);
        for (LL j=a[i+1].a ;j<=a[i].a-1 ;j++)
        {
            ans+=p.top();
            p.pop();
            if (p.empty())
              break;
        }
    }
    printf("%lld\n", ans);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章