种树
题目描述: 某条街被划为 n 条路段,这 n 条路段依次编号为1…n 。每个路段最多可以种一棵树。现在居民们给出了 h 组建议,每组建议包含三个整数 b,e,t,表示居民希望在路段 b 到 e 之间至少要种 t 棵树。这些建议所给路段的区间可以交叉。请问:如果要满足所有居民的建议,至少要种多少棵树。 输入格式: 第一行为 n,表示路段数。 第二行为 h,表示建议数。 下面 h 行描述一条建议:b,e,t,用一个空格分隔。 输出格式: 输出只有一个数,为满足所有居民的建议,所需要种树的最少数量。 样例输入:
9 4 1 4 2 4 6 2 8 9 2 3 5 2
样例输出:
5
数据范围与提示:
30%的数据满足0<n<=1000,0<h<=500; 100%的数据满足0<n<=3*104,h<=5000,0<b<=e<=3*104,t<=e-b+1。
题解:先排序,为了种更少的树,我们先扫描一下该区间,看看种了多少树,如果该区间的树大于等于我们想要的树,就continue。
如果不能达到我们想要的树,就把该区间从后往前种树,直到种到我们想要的树的数量。
遍历所有区间,最后输出最少需要的树。
AC代码:
#include<stdio.h>
#include<algorithm>
using namespace std
;
struct note
{
int b
,e
,t
;
} q
[5010];
int book
[30010];
bool cmp(note x
,note y
)
{
return x
.e
<y
.e
;
}
int main()
{
int n
,h
;
scanf("%d%d",&n
,&h
);
int i
,j
;
for(i
=0; i
<h
; i
++)
scanf("%d%d%d",&q
[i
].b
,&q
[i
].e
,&q
[i
].t
);
sort(q
,q
+h
,cmp
);
int k
,tree
=0;
for(i
=0; i
<h
; i
++)
{
k
=0;
for(j
=q
[i
].b
; j
<=q
[i
].e
; j
++)
{
if(book
[j
])
k
++;
}
if(k
>=q
[i
].t
)
continue;
for(j
=q
[i
].e
; j
>=q
[i
].b
; j
--)
{
if(book
[j
]==0)
{
book
[j
]=1;
k
++;
tree
++;
if(k
==q
[i
].t
)
break;
}
}
}
printf("%d\n",tree
);
return 0;
}