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

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是十有八九的事

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

 1 /**************************************************************
 2     Problem: 3389
 3     User: HansBug
 4     Language: Pascal
 5     Result: Accepted
 6     Time:100 ms
 7     Memory:1008 kb
 8 ****************************************************************/
 9
10 var
11    i,j,k,l,m,n,ans:longint;
12    a:array[0..100000,1..2] of longint;
13 function max(x,y:longint):longint;
14          begin
15               if x>y then max:=x else max:=y;
16          end;
17 procedure swap(var x,y:longint);
18           var z:longint;
19           begin
20                z:=x;x:=y;y:=z;
21           end;
22
23 procedure sort(l,r:longint);
24           var i,j,x,y:longint;
25           begin
26                i:=l;j:=r;x:=a[(l+r) div 2,1];y:=a[(l+r) div 2,2];
27                repeat
28                      while (a[i,1]<x) or ((a[i,1]=x) and (a[i,2]<y)) do inc(i);
29                      while (a[j,1]>x) or ((a[j,1]=x) and (a[j,2]>y)) do dec(j);
30                      if i<=j then
31                         begin
32                              swap(a[i,1],a[j,1]);
33                              swap(a[i,2],a[j,2]);
34                              inc(i);dec(j);
35                         end;
36                until i>j;
37                if i<r then sort(i,r);
38                if l<j then sort(l,j);
39           end;
40 begin
41      readln(n,m);
42      a[0,1]:=0;a[0,2]:=0;
43      for i:=1 to n do readln(a[i,1],a[i,2]);
44      sort(1,n);ans:=0;
45      while l<m do
46            begin
47                 j:=l;
48                 while (k<n) and (a[k+1,1]<=(j+1)) do
49                       begin
50                            inc(k);
51                            l:=max(l,a[k,2]);
52                       end;
53                 if (k=n) and (a[k,2]<m) or (a[k+1,1]>(l+1)) then
54                    begin
55                         writeln(-1);
56                         halt;
57                    end;
58                 inc(ans);
59            end;
60      if l<m then writeln(-1) else writeln(ans);
61 end.   

最短路:这道题个人认为最神奇的做法就是最短路,我们可以以每个时间点为节点,对于所有的(i,i-1)连边权为0的有向边,对于数据所给的时间段(x,y),连(x-1,y)边权为1的有向边,然后求0到T的最短路即可

 1 /**************************************************************
 2     Problem: 3389
 3     User: HansBug
 4     Language: Pascal
 5     Result: Accepted
 6     Time:160 ms
 7     Memory:5132 kb
 8 ****************************************************************/
 9
10 type
11     point=^node;
12     node=record
13                g,w:longint;
14                next:point;
15     end;
16 var
17    i,j,k,l,m,n,f,r:longint;
18    a,b:array[0..60000,1..3] of longint;
19    c,g:array[0..50000] of longint;
20    d:array[0..500000] of longint;
21    e:array[0..50000] of point;
22    p:point;
23 procedure add(x,y,z:longint);
24           var p:point;
25           begin
26                new(p);p^.g:=y;p^.w:=z;p^.next:=e[x];e[x]:=p;
27           end;
28 procedure swap(var x,y:longint);
29           var z:longint;
30           begin
31                z:=x;x:=y;y:=z;
32           end;
33 procedure sort(l,r:longint);
34           var i,j,x,y:longint;
35           begin
36                i:=l;j:=r;x:=b[(l+r) div 2,1];
37                repeat
38                      while b[i,1]<x do inc(i);
39                      while b[j,1]>x do dec(j);
40                      if i<=j then
41                         begin
42                              swap(b[i,1],b[j,1]);
43                              swap(b[i,2],b[j,2]);
44                              swap(b[i,3],b[j,3]);
45                              inc(i);dec(j);
46                         end;
47                until i>j;
48                if i<r then sort(i,r);
49                if l<j then sort(l,j);
50           end;
51
52 begin
53      readln(n,m);
54      for i:=1 to n do
55          begin
56               readln(a[i,1],a[i,2]);a[i,1]:=a[i,1]-1;
57               b[i*2-1,1]:=a[i,1];b[i*2-1,2]:=i;b[i*2-1,3]:=1;
58               b[i*2,1]:=a[i,2];b[i*2,2]:=i;b[i*2,3]:=2;
59          end;
60      b[n*2+1,1]:=m;b[n*2+1,2]:=0;b[n*2+1,3]:=0;
61      sort(1,n*2);
62      b[0,1]:=0;
63      for i:=1 to n*2 do
64          begin
65               if b[i,1]<>b[i-1,1] then inc(j);
66               a[b[i,2],b[i,3]]:=j;
67          end;
68      if b[n*2+1,1]>b[n*2,1] then inc(j);
69      m:=j;
70      for i:=0 to m do e[i]:=nil;
71      for i:=m downto 1 do add(i,i-1,0);
72      for i:=1 to n do add(a[i,1],a[i,2],1);
73      fillchar(c,sizeof(c),0);fillchar(g,sizeof(g),0);
74      c[0]:=1;d[1]:=0;f:=1;r:=2;g[0]:=1;
75      while f<r do
76            begin
77                 p:=e[d[f]];
78                 while p<>nil do
79                       begin
80                            if (c[p^.g]=0) or (c[p^.g]>(c[d[f]]+p^.w)) then
81                               begin
82                                    c[p^.g]:=c[d[f]]+p^.w;
83                                    if g[p^.g]=0 then
84                                       begin
85                                            g[p^.g]:=1;
86                                            d[r]:=p^.g;
87                                            inc(r);
88                                       end;
89                               end;
90                            p:=p^.next;
91                       end;
92                 inc(f);
93                 g[d[f]]:=0;
94            end;
95      for i:=0 to m do dec(c[i]);
96      writeln(c[m]);
97      readln;
98 end.      
时间: 2025-01-13 23:08:42

3389: [Usaco2004 Dec]Cleaning Shifts安排值班的相关文章

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

题目 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MB Description 一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫 打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个时间段必需有奶牛在值班.  那么,最少需要动用多少奶牛参与值班呢?如果没有办法安排出合理的

Bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 最短路,神题

3389: [Usaco2004 Dec]Cleaning Shifts安排值班 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 218  Solved: 86[Submit][Status][Discuss] Description 一天有T(1≤T≤10^6)个时段.约翰正打算安排他的N(1≤N≤25000)只奶牛来值班,打扫 打扫牛棚卫生.每只奶牛都有自己的空闲时间段[Si,Ei](1≤Si≤Ei≤T),只能把空闲的奶牛安排出来值班.而且,每个

bzoj 3389: [Usaco2004 Dec]Cleaning Shifts安排值班 -- 贪心

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

BZOJ3389 [Usaco2004 Dec]Cleaning Shifts安排值班

裸的最短路呢... 建图还是有些微妙的...但是感觉不快啊... 每个时间点建一个点,然后我们建图分两步: (1)i 时间点向 i - 1 号时间点连一条有向边 (2)若有一头牛[l, r],则 l - 1向 r连一条边 最后答案就是dis[T] 想想就觉得非常巧妙...但是慢啊... 1 /************************************************************** 2 Problem: 3389 3 User: rausen 4 Languag

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

思路:可以贪心,也可以最短路. 贪心写法:因为在保证合法的前提下,我们选择的区间一定要右端点尽量靠后才行,于是我们每次就选择一个合法的并且右端点最靠后的区间就好了(如果没有合法的输出-1即可).时间复杂度O(nlogn)(排序是nlogn的,贪心是O(n)的). #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> usi

BZOJ 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚

题目 1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MB Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now require their barn to be immaculate. Farmer John, the most

[BZOJ1672][Usaco2005 Dec]Cleaning Shifts 清理牛棚

1672: [Usaco2005 Dec]Cleaning Shifts 清理牛棚 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 953  Solved: 407 [Submit][Status][Discuss] Description Farmer John's cows, pampered since birth, have reached new heights of fastidiousness. They now require the

[Usaco2005 Dec]Cleaning Shifts

[Usaco2005 Dec]Cleaning Shifts 给出n段区间,左右端点分别为\(l_i,r_i\),以及选取这段区间的费用\(c_i\),现在要选出若干个区间,使其完全覆盖区间\([m,e]\),询问费用之和的最小值,\(1≤n≤10000,0≤m≤e≤86399\). 解 法一: 不妨把区间按左端点排序,如果在大区间范围外,可以筛除,虽然题目有保障,于是设\(f_i\)表示以第i个区间结尾,覆盖第i个区间前所有需要覆盖的位置的最少代价,于是有 \[f_i=\min_{j=1,r_

BZOJ 1672 Usaco 2005 Dec Cleaning Shifts 清理牛棚 动态规划

题目大意:有一些牛,他们的牛舍需要被打扫.有N(N <= 10000)头牛愿意打扫,从时间S到时间T,需要花费一些金钱.问若要每时每刻都有牛在打扫,至少需要花多少钱. 思路:1w的数据量不算很大,再加上时限5s,就n^2动归来做. 将牛按时间段的开始排序. 设f[i]为若取第i头牛打扫,到这头牛结束的时间最小花费是多少. 则    f[i] = min(f[i],f[j] + cost[i])  (f[i].st <= f[j].ed + 1) 最后是初值和答案的问题.由于题目中说每时每刻都有