您的位置:首页 > 其它

3389: [Usaco2004 Dec]Cleaning Shifts安排值班

2015-04-14 21:20 183 查看

3389: [Usaco2004 Dec]Cleaning Shifts安排值班

Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 102 Solved: 46
[Submit][Status][Discuss]

Description

一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫
打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个时间段必需有奶牛在值班. 那么,最少需要动用多少奶牛参与值班呢?如果没有办法安排出合理的方案,就输出-1.

Input

第1行:N,T.
第2到N+1行:Si,Ei.

Output

最少安排的奶牛数.

Sample Input

3 10

1 7

3 6

6 10

Sample Output

2

样例说明

奶牛1和奶牛3参与值班即可.

HINT

Source

Silver

题解:这道题做法有很多,比如:DP(虽然多半会TLE)、贪心、甚至最短路

DP:不用多说,就是通过各个区间进行对于前面的转移,所以需要用到一个快速的区间查询数据结构进行维护,但是很可惜,时限是1s,而T<=1000000,TLE是十有八九的事

贪心:显然,对于多个结束时间相同的区间来说,保留一个起始时间最长的即可,于是我们开始进行贪心

/**************************************************************
Problem: 3389
User: HansBug
Language: Pascal
Result: Accepted
Time:100 ms
Memory:1008 kb
****************************************************************/

var
i,j,k,l,m,n,ans:longint;
a:array[0..100000,1..2] of longint;
function max(x,y:longint):longint;
begin
if x>y then max:=x else max:=y;
end;
procedure swap(var x,y:longint);
var z:longint;
begin
z:=x;x:=y;y:=z;
end;

procedure sort(l,r:longint);
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=a[(l+r) div 2,1];y:=a[(l+r) div 2,2];
repeat
while (a[i,1]<x) or ((a[i,1]=x) and (a[i,2]<y)) do inc(i);
while (a[j,1]>x) or ((a[j,1]=x) and (a[j,2]>y)) do dec(j);
if i<=j then
begin
swap(a[i,1],a[j,1]);
swap(a[i,2],a[j,2]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if l<j then sort(l,j);
end;
begin
readln(n,m);
a[0,1]:=0;a[0,2]:=0;
for i:=1 to n do readln(a[i,1],a[i,2]);
sort(1,n);ans:=0;
while l<m do
begin
j:=l;
while (k<n) and (a[k+1,1]<=(j+1)) do
begin
inc(k);
l:=max(l,a[k,2]);
end;
if (k=n) and (a[k,2]<m) or (a[k+1,1]>(l+1)) then
begin
writeln(-1);
halt;
end;
inc(ans);
end;
if l<m then writeln(-1) else writeln(ans);
end.


最短路:这道题个人认为最神奇的做法就是最短路,我们可以以每个时间点为节点,对于所有的(i,i-1)连边权为0的有向边,对于数据所给的时间段(x,y),连(x-1,y)边权为1的有向边,然后求0到T的最短路即可,还有——对于P党来说一个很大的重点在于离散化,必须把一些只指向前一个节点而且边权还为0的给压缩,这样子可以节省大量时间,我原来简单的最短路居然TLE,离散化之后就AC了(HansBug:感谢phile神犇的离散化点子么么哒)

/**************************************************************
Problem: 3389
User: HansBug
Language: Pascal
Result: Accepted
Time:160 ms
Memory:5132 kb
****************************************************************/

type
point=^node;
node=record
g,w:longint;
next:point;
end;
var
i,j,k,l,m,n,f,r:longint;
a,b:array[0..60000,1..3] of longint;
c,g:array[0..50000] of longint;
d:array[0..500000] of longint;
e:array[0..50000] of point;
p:point;
procedure add(x,y,z:longint);
var p:point;
begin
new(p);p^.g:=y;p^.w:=z;p^.next:=e[x];e[x]:=p;
end;
procedure swap(var x,y:longint);
var z:longint;
begin
z:=x;x:=y;y:=z;
end;
procedure sort(l,r:longint);
var i,j,x,y:longint;
begin
i:=l;j:=r;x:=b[(l+r) div 2,1];
repeat
while b[i,1]<x do inc(i);
while b[j,1]>x do dec(j);
if i<=j then
begin
swap(b[i,1],b[j,1]);
swap(b[i,2],b[j,2]);
swap(b[i,3],b[j,3]);
inc(i);dec(j);
end;
until i>j;
if i<r then sort(i,r);
if l<j then sort(l,j);
end;

begin
readln(n,m);
for i:=1 to n do
begin
readln(a[i,1],a[i,2]);a[i,1]:=a[i,1]-1;
b[i*2-1,1]:=a[i,1];b[i*2-1,2]:=i;b[i*2-1,3]:=1;
b[i*2,1]:=a[i,2];b[i*2,2]:=i;b[i*2,3]:=2;
end;
b[n*2+1,1]:=m;b[n*2+1,2]:=0;b[n*2+1,3]:=0;
sort(1,n*2);
b[0,1]:=0;
for i:=1 to n*2 do
begin
if b[i,1]<>b[i-1,1] then inc(j);
a[b[i,2],b[i,3]]:=j;
end;
if b[n*2+1,1]>b[n*2,1] then inc(j);
m:=j;
for i:=0 to m do e[i]:=nil;
for i:=m downto 1 do add(i,i-1,0);
for i:=1 to n do add(a[i,1],a[i,2],1);
fillchar(c,sizeof(c),0);fillchar(g,sizeof(g),0);
c[0]:=1;d[1]:=0;f:=1;r:=2;g[0]:=1;
while f<r do
begin
p:=e[d[f]];
while p<>nil do
begin
if (c[p^.g]=0) or (c[p^.g]>(c[d[f]]+p^.w)) then
begin
c[p^.g]:=c[d[f]]+p^.w;
if g[p^.g]=0 then
begin
g[p^.g]:=1;
d[r]:=p^.g;
inc(r);
end;
end;
p:=p^.next;
end;
inc(f);
g[d[f]]:=0;
end;
for i:=0 to m do dec(c[i]);
writeln(c[m]);
readln;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: