描述
某条街被划为 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。
解题思路
一题简单的贪心题。将需要种树的根据右端点从小到大排序,然后从前往后遍历种树。
代码
#include<bits/stdc++.h>
using namespace std;
struct node
{
int a,b,tree;
}dir[5005];
bool cmp(node x,node y)
{
if(x.b!=y.b)
return x.b<y.b;
else return x.a>y.a;
}
bool map1[30005];
int main()
{
int n;
int l;
scanf("%d",&l);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d %d %d",&dir[i].a,&dir[i].b,&dir[i].tree);
}
sort(dir,dir+n,cmp);//将区间排序
int sum=0;
for(int i=0;i<n;i++) //从前往后遍历
{
int s=0;
for(int j=dir[i].a;j<=dir[i].b&&s<dir[i].tree;j++)
{
if(map1[j])
s++; //计算这个区间已经有多少棵树了
}
for(int j=dir[i].b;j>=dir[i].a&&s<dir[i].tree;j--) //要种树从区间后面往前
{
if(!map1[j])
{
s++;
sum++;//要种的树累加
map1[j]=1; //标记该位置已经种树了
}
}
}
printf("%d\n",sum);
return 0;
}