种树 (codevs 1653) 题解

【问题描述】

    一条街的一边有几座房子。因为环保原因居民想要在路边种些树。路边的地区被分割成块,并被编号为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.

 

你可能感兴趣的:(code)