pku3171 Cleaning Shifts
有一个仓库,在时间段[M,E]需要一直被打扫。现在有n头奶牛来干这项工作。每头奶牛都有一个工作时间段[start,final],并且需要付的费用是cost。问题是聘用哪些奶牛能使费用最少?允多头奶牛在同一时间工作。
先把区间按照final升序排列,然后进行DP,考虑到范围较大,O(L^2)超时,引入线段树进行优化,将决策的复杂度降到logn。
还要输出-1,WA死了。。。
这是我的pku第100题,庆祝啊,激动死了。。
View Code
1 program pku3171(input,output); 2 type 3 node=record 4 left,right,x,y:longint; 5 minn:longint; 6 end; 7 var 8 tree:array[0..180000] of node; 9 f :array[0..90000] of longint; 10 start,final,cost:array[0..11000] of longint; 11 n,m,e:longint; 12 tot:longint; 13 maxl:longint; 14 function min(aa,bb:longint):longint; 15 begin 16 if aa<bb then 17 exit(aa); 18 exit(bb); 19 end;{ min } 20 procedure build(xx,yy:longint); 21 var 22 now,mid:longint; 23 begin 24 inc(tot); 25 now:=tot; 26 tree[now].x:=xx; 27 tree[now].y:=yy; 28 if xx=yy then 29 begin 30 tree[now].minn:=19950714; 31 exit; 32 end; 33 mid:=(xx+yy)>>1; 34 tree[now].left:=tot+1; 35 build(xx,mid); 36 tree[now].right:=tot+1; 37 build(mid+1,yy); 38 tree[now].minn:=19950714; 39 end;{ build } 40 procedure change(now,poss,worth:longint); 41 var 42 mid:longint; 43 begin 44 if tree[now].x=tree[now].y then 45 begin 46 tree[now].minn:=worth; 47 exit; 48 end; 49 mid:=(tree[now].x+tree[now].y)>>1; 50 if poss<=mid then 51 change(tree[now].left,poss,worth) 52 else 53 change(tree[now].right,poss,worth); 54 tree[now].minn:=min(tree[tree[now].left].minn,tree[tree[now].right].minn); 55 end;{ change } 56 function find(now,xx,yy:longint):longint; 57 var 58 mid:longint; 59 begin 60 if (tree[now].x=xx)and(tree[now].y=yy) then 61 exit(tree[now].minn); 62 mid:=(tree[now].x+tree[now].y)>>1; 63 if yy<=mid then 64 exit(find(tree[now].left,xx,yy)) 65 else 66 if xx>mid then 67 exit(find(tree[now].right,xx,yy)) 68 else 69 exit(min(find(tree[now].left,xx,mid),find(tree[now].right,mid+1,yy))); 70 end;{ find } 71 procedure swap(var aa,bb:longint); 72 var 73 tt:longint; 74 begin 75 tt:=aa; 76 aa:=bb; 77 bb:=tt; 78 end;{ swap } 79 procedure sort(p,q:longint); 80 var 81 i,j,mid:longint; 82 begin 83 i:=p; 84 j:=q; 85 mid:=final[(i+j)>>1]; 86 repeat 87 while final[i]<mid do 88 inc(i); 89 while final[j]>mid do 90 dec(j); 91 if i<=j then 92 begin 93 swap(start[i],start[j]); 94 swap(final[i],final[j]); 95 swap(cost[i],cost[j]); 96 inc(i); 97 dec(j); 98 end; 99 until i>j; 100 if i<q then sort(i,q); 101 if j>p then sort(p,j); 102 end;{ sort } 103 procedure init; 104 var 105 i:longint; 106 begin 107 readln(n,m,e); 108 tot:=0; 109 maxl:=0; 110 for i:=1 to n do 111 begin 112 readln(start[i],final[i],cost[i]); 113 if final[i]>maxl then 114 maxl:=final[i]; 115 end; 116 build(0,maxl); 117 sort(1,n); 118 end;{ init } 119 function max(aa,bb:longint):longint; 120 begin 121 if aa>bb then 122 exit(aa); 123 exit(bb); 124 end;{ max} 125 procedure main; 126 var 127 i,j:longint; 128 begin 129 fillchar(f,sizeof(f),63); 130 change(1,m,0); 131 f[m]:=0; 132 for i:=1 to n do 133 begin 134 j:=find(1,max(start[i]-1,0),final[i]); 135 if j+cost[i]<f[final[i]] then 136 begin 137 f[final[i]]:=j+cost[i]; 138 change(1,final[i],f[final[i]]); 139 end; 140 end; 141 end;{ main } 142 procedure print; 143 begin 144 if f[e]>=19950714 then 145 writeln(-1) 146 else 147 writeln(f[e]); 148 end;{ print } 149 begin 150 init; 151 main; 152 print; 153 end.