种树
题目描述
一条街道的一边有几座房子,因为环保原因居民想要在路边种些树,路边的居民被分割成 n 块,并被编号为 1…n。每块大小为一个单位尺寸并最多可种一棵树。每个居民想在门前种些树并指定了三个数b,e,t。这三个数分别表示该居民想在b和e之间最少种t棵树,当然b≤e,t≤e-b+1,允许居民想种树的子区域可以交叉。出于资金紧缺的原因,环保部门请你求出能够满足所有居民的种树要求时所需要种的树的最少数量。
输入
第一行为 n,表示区域的个数。
第二行为 h,表示房子的数目。
下面 h 行描述居民的需要:b,e,t(0<b≤e≤30000,t≤e-b+1)分别用一个空格分开。
第二行为 h,表示房子的数目。
下面 h 行描述居民的需要:b,e,t(0<b≤e≤30000,t≤e-b+1)分别用一个空格分开。
输出
输出只有一个数,为满足所有居民的建议,所需要种树的最少数量。
样例输入
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。
100% 的数据满足 0<n≤3×10^4,h≤5000,0<b≤e≤3×10^4 ,t≤e−b+1。
解析:贪心,按左端点从小到大排序,然后倒续从每个的左向右种树。
代码如下:
#include<bits/stdc++.h>
using namespace std;
bool a[30001];
struct Nd
{
int s,t,num;
}q[5001];
bool cmp(Nd a,Nd b)
{
return a.s<b.s;
}
int ans;
int main()
{
int n,h;
scanf("%d%d",&n,&h);
for(int i=1;i<=h;i++)
{
scanf("%d%d%d",&q[i].s,&q[i].t,&q[i].num);
}
sort(q+1,q+h+1,cmp);
for(int i=h;i>=1;i--)
{
for(int j=q[i].s;j<=q[i].t;j++)
{
if(a[j]) q[i].num--;
}
if(q[i].num<=0) continue;
for(int j=q[i].s;j<=q[i].t;j++)
{
if(!a[j])
{
a[j]=1;
q[i].num--;
}
if(q[i].num<=0) break;
}
}
for(int i=1;i<=n;i++)
{
ans+=a[i];
}
cout<<ans;
return 0;
}
/*
7
3
2 5 1
2 6 2
3 7 1
*/