题目
题目描述
一条街道的一边有几座房子,因为环保原因居民想要在路边种些树,路边的居民被分割成 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)分别用一个空格分开。
输出
输出只有一个数,为满足所有居民的建议,所需要种树的最少数量。
样例输入
9
4
1 4 2
4 6 2
8 9 2
3 5 2
样例输出
5
分析
终于发一篇正经的了~~~
这道题就是一个结构体+贪心
代码
#include<bits/stdc++.h> using namespace std; struct tree{ int b,e,t; }a[30001]; int n,h,ans; bool vis[30001]; bool cmp(tree x,tree y){ return x.e<y.e; } int main() { scanf("%d%d",&n,&h); for(int i=1;i<=h;i++){ scanf("%d%d%d",&a[i].b,&a[i].e,&a[i].t); } sort(a+1,a+h+1,cmp); for(int i=1;i<=h;i++){ int dl=0; for(int j=a[i].b;j<=a[i].e;j++){ if(vis[j]) dl++;//判断之前是否种树 } if(dl>=a[i].t) continue;//如果够,则跳过此区域 for(int j=a[i].e;j>=a[i].b;j--){//从右往左 if(!vis[j]){//如果没有种树 vis[j]=1;//种树 dl++; ans++; if(dl==a[i].t) break;//若够,则终止循环 } } } printf("%d",ans); return 0; }