51nod 1163 最高的獎勵(優先佇列+貪心)
題目:
原題如下:
有N個任務,每個任務有一個最晚結束時間以及一個對應的獎勵。在結束時間之前完成該任務,就可以獲得對應的獎勵。完成每一個任務所需的時間都是1個單位時間。有時候完成所有任務是不可能的,因為時間上可能會有衝突,這需要你來取捨。求能夠獲得的最高獎勵。 Input 第1行:一個數N,表示任務的數量(2 <= N <= 50000) 第2 - N + 1行,每行2個數,中間用空格分隔,表示任務的最晚結束時間E[i]以及對應的獎勵W[i]。(1 <= E[i] <= 10^9,1 <= W[i] <= 10^9) Output 輸出能夠獲得的最高獎勵。 Input示例 7 4 20 2 60 4 70 3 40 1 30 4 50 6 10 Output示例 230
思路:
如果只用普通的貪心是可以的,因為這個題他有個隱藏的條件,那就是可以提前用。 如果題目是說這個題只能在這一刻做,那麼就直接貪心,但是這個可以提前。 也就是說對於t時刻時,我們一共最多能完成t-1個題,但是這t-1個題,只要是在規定時間內即可。 我們遍歷所有的題目,對於當前題目,得到他是最晚執行時間z。 如果佇列(我們做了的題目)數量小於z,也就是說我們這個z這個題目可以做,直接做即可。 如果數量大於等於z了,我們這道題做還是不做,要看看裡面還有沒有更小的,把獲得價值最小的題目取出來,把這個放進去即可。 對於這種最晚執行,這種要求的題目,用到了優先佇列。 原文:https://blog.csdn.net/little_boy_z/article/details/78501710?utm_source=copy
C++佇列Queue類成員函式有:
back() 返回最後一個元素
empty() 如果佇列空則返回真
front() 返回第一個元素
pop() 刪除第一個元素
size() 返回佇列中元素的個數
AC程式碼:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; struct node { int time; int val; }a[50010]; bool cmp(node t1,node t2) { if(t1.time==t2.time) return t1.val>t2.val; else return t1.time<t2.time; } int main() { int i,j,n; scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d%d",&a[i].time,&a[i].val); } sort(a,a+n,cmp); long long int ans=0; //ans最後加起來有可能超過int的 priority_queue<int,vector<int>,greater<int> > pq; for(int i=0;i<n;i++) { int k=a[i].val; if(a[i].time>pq.size())//要插入的截止時間大於已加入任務用的總時間 { ans+=k; pq.push(k); } else { ans+=k; pq.push(k); int t=pq.top(); //替換掉棧頂那個價值最小的 pq.pop(); ans-=t; } } cout<<ans<<endl; return 0; }