Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 814 Solved: 365
Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间。 他的工作日从0时刻开始,有1000000000个单位时间(!)。在任一时刻,他都可以选择编号1~N的N(1 <= N <= 100000)项工作中的任意一项工作来完成。 因为他在每个单位时间里只能做一个工作,而每项工作又有一个截止日期,所以他很难有时间完成所有N个工作,虽然还是有可能。 对于第i个工作,有一个截止时间D_i(1 <= D_i <= 1000000000),如果他可以完成这个工作,那么他可以获利P_i( 1<=P_i<=1000000000 ). 在给定的工作利润和截止时间下,FJ能够获得的利润最大为多少呢?答案可能会超过32位整型。
第1行:一个整数N. 第2~N+1行:第i+1行有两个用空格分开的整数:D_i和P_i.
输出一行,里面有一个整数,表示最大获利值。
3 2 10 1 5 1 7
17
第1个单位时间完成第3个工作(1,7),然后在第2个单位时间完成第1个工作(2,10)以达到最大利润
题解:一个比较经典的问题,直接建立一个堆,然后倒着来,到每个时间节点就加上一波,然后将最大的一坨取出来即可
1 var
2 i,j,k,l,m,n,head:longint;
3 ans:int64;
4 b:array[0..200000,1..2] of longint;
5 a,lef,rig,fix:array[0..200000] of longint;
6 function min(x,y:longint):longint;inline;
7 begin
8 if x<y then min:=x else min:=y;
9 end;
10
11 procedure swap(var x,y:longint);inline;
12 var z:longint;
13 begin
14 z:=x;x:=y;y:=z;
15 end;
16 procedure sort(l,r:longint);inline;
17 var i,j,x,y:longint;
18 begin
19 i:=l;j:=r;x:=b[(l+r) div 2,2];
20 repeat
21 while b[i,2]>x do inc(i);
22 while b[j,2]<x do dec(j);
23 if i<=j then
24 begin
25 swap(b[i,1],b[j,1]);
26 swap(b[i,2],b[j,2]);
27 inc(i);dec(j);
28 end;
29 until i>j;
30 if i<r then sort(i,r);
31 if l<j then sort(l,j);
32 end;
33 procedure merge(var x,y:longint);inline;
34 begin
35 if x=0 then swap(x,y);
36 if y=0 then exit;
37 if a[x]<a[y] then swap(x,y);
38 merge(rig[x],y);
39 fix[x]:=min(fix[lef[x]],fix[rig[x]])+1;
40 if fix[lef[x]]<fix[rig[x]] then swap(lef[x],rig[x]);
41 end;
42 function cuthead(var head:longint):longint;inline;
43 begin
44 cuthead:=a[head];
45 merge(lef[head],rig[head]);
46 head:=lef[head];
47 end;
48 begin
49 readln(n);m:=0;head:=0;
50 for i:=1 to n do readln(b[i,2],b[i,1]);
51 sort(1,n);
52 j:=1;
53 ans:=0;
54 while true do
55 begin
56 i:=j;
57 if b[i,2]<=0 then break;
58 while b[i,2]=b[j,2] do inc(i);
59 for k:=j to i-1 do
60 begin
61 inc(m);l:=m;
62 a[m]:=b[k,1];lef[m]:=0;rig[m]:=0;fix[m]:=0;
63 merge(head,l);
64 end;
65 for k:=1 to b[j,2]-b[i,2] do
66 begin
67 if head=0 then break;
68 ans:=ans+cuthead(head);
69 end;
70 j:=i;
71 end;
72 writeln(ans);
73 readln;
74 end.
75