【问题描述】
一条街的一边有几座房子。因为环保原因居民想要在路边种些树。路边的地区被分割成块,并被编号为1..n。每个块大小为一个单位尺寸并最多可种一棵树。每个居民想在门前种些树并指定了三个号码b,e,t。这三个数表示该居民想在b和e之间最少种t棵树。当然b<=e,居民必须保证在指定地区不能种多于地区被分割成块数的树,即要求t<=e-b+1。允许居民想种树的各自区域可以交叉。出于资金短缺的原因,环保部门请你求出能够满足所有居民的要求,需要种树的最少数量。
【样例输入】
9
4
1 4 2
4 6 2
8 9 2
3 5 2
【样例输出】
5
【解题思路】
本题用贪心算法,先以b为关键字排序,然后从后往前种,因为这样与后面的重合的可能性才越大,定义一个布尔型数组,每种一棵,就赋为true,最后计算true的数量即可。
【代码实现】
1 type rec=record
2 b,e,t:longint;
3 end;
4 var a:array[1..30000] of rec;
5 f:array[1..30000] of boolean;
6 i,j,n,m,ans:longint;
7 procedure sort(l,r:longint);
8 var i,j,x:longint;
9 y:rec;
10 begin
11 i:=l;
12 j:=r;
13 x:=a[(l+r) div 2].e;
14 repeat
15 while a[i].e<x do
16 inc(i);
17 while x<a[j].e do
18 dec(j);
19 if not(i>j) then
20 begin
21 y:=a[i];
22 a[i]:=a[j];
23 a[j]:=y;
24 inc(i);
25 j:=j-1;
26 end;
27 until i>j;
28 if l<j then
29 sort(l,j);
30 if i<r then
31 sort(i,r);
32 end;
33 function pd(t:longint):longint;
34 var i,ans:longint;
35 begin
36 ans:=0;
37 for i:=a[t].b to a[t].e do
38 if f[i] then inc(ans);
39 exit(ans);
40 end;//判断当前区间种了几棵树
41 procedure hh;
42 var t,tt:longint;
43 begin
44 for t:=1 to n do
45 begin
46 if pd(t)<a[t].t then
47 begin
48 tt:=a[t].e;f[tt]:=true;
49 end;
50 while pd(t)<a[t].t do//还没种完,继续往前种
51 begin
52 dec(tt);
53 f[tt]:=true;
54 end;
55 end;
56 end;
57 begin
58 readln(m);
59 readln(n);
60 for i:=1 to n do
61 with a[i] do
62 readln(b,e,t);
63 sort(1,n);
64 hh;
65 for i:=1 to m do
66 if f[i] then
67 inc(ans);
68 writeln(ans);
69 end.
来源:https://www.cnblogs.com/PengBoLiuXu/p/4486940.html