题目描述
某条街被划为 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×10^4,h≤5000,0<b≤e≤3×10^4,t≤e−b+1。
区间问题。按右端点的升序排序,将树尽可能的往右端点种。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<vector>
#include<stack>
using namespace std;
struct node
{
int l,r,num;
friend bool operator <(node a,node b)
{
return a.r<b.r;
}
}sugg[5001];//suggestion
int main()
{
int n,h,ans=0;
bool isplan[30001];//is planted
memset(isplan,0,sizeof(isplan));
cin>>n>>h;
for(int i=1;i<=h;i++)
cin>>sugg[i].l>>sugg[i].r>>sugg[i].num;
sort(sugg+1,sugg+h+1);
for(int i=1;i<=h;i++)
{
int t=0;//当前建议已种树数目
for(int j=sugg[i].r;j>=sugg[i].l;j--) t+=isplan[j];
for(int j=sugg[i].r;j>=sugg[i].l&&t<sugg[i].num;j--)
if(!isplan[j]) isplan[j]=1,ans++,t++;
}
cout<<ans;
}