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.
posted @ 2012-04-19 17:58  Codinginging  阅读(486)  评论(0编辑  收藏  举报