POJ 2376
POJ 2376 Cleaning Shifts
题目大意:有n只牛和t项工作,每只牛可以执行x至y项工作,求最少的牛可以把每件工作至少执行一次。
解法:由于1<=n<=25,000;1<=T<=1,000,000;由此看出不是搜索,仔细观察发现是一个求最少线段覆盖一条线段的模型。
先置s=0,将线段按x关键字排序,然后开始贪心,每次选可以覆盖到s的(x-1<=s)且y最大的线段,然后更新s:=y;
贪心的思想…注意处理无解如何退出,这里我觉得我需要回去仔细研究下如何退出循环,虽然AC,但并不代表完美。
{突然发现自己的风格改了对不上号了囧}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 {2011.11.20
2 poj P2376
3 USACO 2004 December Sliver}
4 const
5 maxn=25000;
6 maxt=1000000;
7 type
8 data=record
9 x, y: longint;
10 end;
11 var
12 a: array[1..maxn]of data;
13 f: array[0..maxt]of boolean;
14 n, t, ans: longint;
15 procedure qsort(b, e: longint);
16 var
17 i, j, x: longint;
18 k: data;
19 begin
20 i := b;
21 j := e;
22 x := a[(i+j)shr 1].x;
23 repeat
24 while a[i].x<x do inc(i);
25 while a[j].x>x do dec(j);
26 if i<=j then
27 begin
28 k := a[i];
29 a[i] := a[j];
30 a[j] := k;
31 inc(i);
32 dec(j);
33 end;
34 until i>j;
35 if j>b then qsort(b, j);
36 if i<e then qsort(i, e);
37 end;
38
39 procedure init;
40 var
41 i: longint;
42 begin
43 fillchar(f, sizeof(f), 0);
44 f[0] := true;
45 ans := 0;
46
47 readln(n, t);
48 for i := 1 to n do
49 with a[i] do
50 readln(x, y);
51 qsort(1, n);
52 end;
53
54 procedure main;
55 var
56 i, j, s: longint;
57 begin
58 s := 0;
59 i := 0;
60 while s<t do
61 begin
62 inc(i);
63 if a[i].x>s+1 then exit;
64 j := i;
65 while (f[a[i].x-1]) do
66 begin
67 if a[i].y>a[j].y then j := i;
68 inc(i);
69 if i>n then break;
70 end;
71 if i<>j then
72 for i := s+1 to a[j].y do
73 f[i] := true;
74 s := a[j].y;
75 i := j;
76 inc(ans);
77 end;
78 end;
79
80 procedure print;
81 var
82 i: longint;
83 begin
84 for i := t downto 1 do
85 if f[i]=false then
86 ans := -1;
87 writeln(ans);
88 end;
89
90 begin
91 //assign(input,'test.in'); reset(input);
92 init;
93 main;
94 print;
95 end.