1. 程式人生 > >51Nod 最高獎勵問題

51Nod 最高獎勵問題

names 表示 con bre prior def out show bubuko

Question 有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



我想到的第一個思路是:
很麻煩的。。
emm,,
趕時間的話,可忽略。
(按照他能獲得的獎勵從大到小排序)
(如果相等,就讓結束時間靠後的在前面)
(然後用一個數組記錄1到1,1到2,1到3,……1到結束時間最大的那個的空間,也就是在這個空間內,和這個數相等或者小於他的有多少)
(用一個bool數組記錄在某個時間結束這個時間點是否出現過)
(然後循環枚舉,沒有出現就設為出現,ans+=獎勵)
(操作時同時,這個時間點到最大的時間點之間所有的記錄數組都要減一,)
(因為在此空間裏又多加了一個數,所以少一個空間)
(然後若是遇到了結束時間相等的,)
(那就判斷一下他前面那個結束時間的位置有沒有被占)
(他前面那個結束時間不是排完序的那個,,是按照1,2,3,4,5……來的那個)
(如果也被占了的話,就繼續往前推)
(在此過程中如果這個結束時間對應的記錄空間的數組等於0的話,(那其實一開始就是0了),)
(那就break掉,不用再繼續了)。
嗯,,基本就是這樣,,
開了很多數組,思路也很麻煩,
可能寫錯了。。
剛開始mle,,最後wa了一個點,t了三四個點。。

代碼是這樣的。:

技術分享圖片
#include<iostream>
#include
<cstdio> #include<cmath> #include<algorithm> #include<cstring> #define MAXN 9999 using namespace std; int n,maxn=-1; int b[MAXN],x,s; long long ans; bool c[MAXN],q; struct node{ int end; int value; }a[50002]; bool cmp(node x,node y) { if(x.value !=y.value ) return x.value >y.value ; else return x.end >y.end ; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%d%d",&a[i].end ,&a[i].value ); maxn=max(maxn,a[i].end ); } for(int i=1;i<=maxn;++i) b[i]=i; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;++i) { x=a[i].end ; s=a[i].value ; if(b[x]) { if(!c[x]) { ans+=s; c[x]=1; for(int j=x;j<=maxn;++j) b[j]--; continue; } while(c[x]) { x--; if(x==0) break; if(!c[x]&&b[x]) { c[x]=1; ans+=s; for(int j=x;j<=maxn;++j) b[j]--; break; } } } } printf("%lld",ans); return 0; }
75.。


還是要考慮別的簡單的思路。。

小根堆啊!!!
按照結束時間從小到大排序!
按次序加,
如果有更優的,就把最小的踢出去!!

具體看代碼吧!
手模一遍樣例就懂了!
好強的貪心思路。。。

代碼:


 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 
 8 priority_queue<int ,vector<int >,greater<int> >q;
 9 long long n,ans,s;
10 
11 struct node
12 {
13     int end,value;
14 } a[50002];
15 
16 bool cmp(node a,node b)
17 {
18     return a.end<b.end;
19 }
20 
21 int main()
22 {
23     scanf("%d",&n);
24     for(int i=1; i<=n; i++)
25         scanf("%d%d",&a[i].end,&a[i].value);
26     sort(a+1,a+1+n,cmp);
27     for(int i=1; i<=n; i++)
28     {
29         s=a[i].value;
30         if(a[i].end>q.size())
31         {
32             ans+=s;
33             q.push(s);
34         }
35         else
36         {
37             ans+=s;
38             q.push(s);
39             ans-=q.top();
40             q.pop();
41         }
42     }
43     printf("%lld",ans);
44     return 0;
45 }


如果你不開心,那我就把右邊技術分享圖片這個帥傻子分享給你吧,

你看,他這麽好看,那麽深情的望著你,你還傷心嗎?

真的!這照片盯上他五秒鐘就想笑了。

一切都會過去的。

 

51Nod 最高獎勵問題