poj2373

其实这道题不是很难,不难想到f[i]表示覆盖到[0,i]的最少喷头数

很明显是一个dp+单调队列的问题

但是细节问题比较多,首先是不能覆盖到[0,l]外面,所以长度为奇数不能被完全覆盖

还有一些区间[bi,ei]只能被一个喷头覆盖,这意味着[0,s],bi<s<ei也是不能被完全覆盖的

标记一下就好了

最后注意判断一下是否可行

  1 const inf=100000007;
  2 type node=record
  3        x,y:longint;
  4      end;
  5 var f,q:array[0..1000010] of longint;
  6     can:array[0..1000010] of boolean;
  7     a,b:array[0..1010] of longint;
  8     p,n,l,w,v,i,j,h,t,ans:longint;
  9 
 10 procedure sort(l,r: longint);
 11   var i,j,x,y: longint;
 12   begin
 13     i:=l;
 14     j:=r;
 15     x:=a[(l+r) shr 1];
 16     repeat
 17       while a[i]<x do inc(i);
 18       while x<a[j] do dec(j);
 19       if not(i>j) then
 20       begin
 21         swap(a[i],a[j]);
 22         swap(b[i],b[j]);
 23         inc(i);
 24         j:=j-1;
 25       end;
 26     until i>j;
 27     if l<j then sort(l,j);
 28     if i<r then sort(i,r);
 29   end;
 30 
 31 procedure merge;
 32   var l,r:longint;
 33   begin
 34     l:=a[1];
 35     r:=b[1];
 36     t:=0;
 37     for i:=2 to n do
 38     begin
 39       if a[i]<r then r:=max(r,b[i])
 40       else begin
 41         if r-l>v*2 then
 42         begin
 43           writeln(-1);
 44           halt;
 45         end;
 46         inc(t);
 47         a[t]:=l;
 48         b[t]:=r;
 49         l:=a[i];
 50         r:=b[i];
 51       end;
 52     end;
 53     if r-l>v*2 then
 54     begin
 55       writeln(-1);
 56       halt;
 57     end;
 58     inc(t);
 59     a[t]:=l;
 60     b[t]:=r;
 61   end;
 62 
 63 begin
 64   readln(n,l);
 65   readln(w,v);
 66   for i:=1 to n do
 67     readln(a[i],b[i]);
 68   sort(1,n);
 69   merge;
 70   for i:=1 to t do
 71     for j:=a[i]+1 to b[i]-1 do
 72       can[j]:=true;
 73   f[0]:=0;
 74   h:=1;
 75   t:=1;
 76   for i:=1 to l do
 77   begin
 78     f[i]:=inf;
 79     p:=i-2*w;
 80     if (p>=0) then
 81     begin
 82       while (t>1) and (h<t) and (f[q[t-1]]>=f[p]) do dec(t);
 83       if not can[p] then
 84       begin
 85         q[t]:=p;
 86         inc(t);
 87       end;
 88     end;
 89     if (can[i]) or (i mod 2=1) then continue;
 90     while (h<t) and (q[h]<i-2*v) do inc(h);
 91     if (h<t) then f[i]:=f[q[h]]+1;
 92   end;
 93   if f[l]>=inf then writeln(-1) else writeln(f[l]);
 94 end.
 95 const inf=100000007;
 96 type node=record
 97        x,y:longint;
 98      end;
 99 var f,q:array[0..1000010] of longint;
100     can:array[0..1000010] of boolean;
101     a,b:array[0..1010] of longint;
102     p,n,l,w,v,i,j,h,t,ans:longint;
103 
104 procedure sort(l,r: longint);
105   var i,j,x,y: longint;
106   begin
107     i:=l;
108     j:=r;
109     x:=a[(l+r) shr 1];
110     repeat
111       while a[i]<x do inc(i);
112       while x<a[j] do dec(j);
113       if not(i>j) then
114       begin
115         swap(a[i],a[j]);
116         swap(b[i],b[j]);
117         inc(i);
118         j:=j-1;
119       end;
120     until i>j;
121     if l<j then sort(l,j);
122     if i<r then sort(i,r);
123   end;
124 
125 procedure merge;
126   var l,r:longint;
127   begin
128     l:=a[1];
129     r:=b[1];
130     t:=0;
131     for i:=2 to n do
132     begin
133       if a[i]<r then r:=max(r,b[i])
134       else begin
135         if r-l>v*2 then
136         begin
137           writeln(-1);
138           halt;
139         end;
140         inc(t);
141         a[t]:=l;
142         b[t]:=r;
143         l:=a[i];
144         r:=b[i];
145       end;
146     end;
147     if r-l>v*2 then
148     begin
149       writeln(-1);
150       halt;
151     end;
152     inc(t);
153     a[t]:=l;
154     b[t]:=r;
155   end;
156 
157 begin
158   readln(n,l);
159   readln(w,v);
160   for i:=1 to n do
161     readln(a[i],b[i]);
162   sort(1,n);
163   merge;
164   for i:=1 to t do
165     for j:=a[i]+1 to b[i]-1 do
166       can[j]:=true;
167   f[0]:=0;
168   h:=1;
169   t:=1;
170   for i:=1 to l do
171   begin
172     f[i]:=inf;
173     p:=i-2*w;
174     if (p>=0) then
175     begin
176       while (t>1) and (h<t) and (f[q[t-1]]>=f[p]) do dec(t);
177       if not can[p] then
178       begin
179         q[t]:=p;
180         inc(t);
181       end;
182     end;
183     if (can[i]) or (i mod 2=1) then continue;
184     while (h<t) and (q[h]<i-2*v) do inc(h);
185     if (h<t) then f[i]:=f[q[h]]+1;
186   end;
187   if f[l]>=inf then writeln(-1) else writeln(f[l]);
188 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473260.html