写在前面
咕了这么久的博客也该写写了,最近吃饭都吃不饱的博主实在是没什么动力学习.....
题目链接
思路
想要种树种得少,就要一棵树在多个区间同时出现。
所以,在重叠部分种尽可能多的树即可。
然而重叠部分一定在区间的尾部。
所以先对结束苇子进行排序,然后依次在区间的尾部从前往后种树直到满足要求,对于下一个区间,看看差多少树,就在结尾补多少。
于是贪心的思想就很容易出来了:
1.按结束位置排序
2.对每个区间一次处理
1.从前往后扫描区间,统计已有的树的个数
2.若已选点超过要求个数,则continue
3.否则从后往前,添加缺少的覆盖点
3.输出ans
注意
注意(n,m)的含义,被坑了!
代码
#include<bits/stdc++.h>
using namespace std;
const int N=300006;
struct node
{
int u,v,w;
}a[N];
int ans;
int n,m,used[N];
int cmp(node a,node b)
{
return a.v<b.v;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;++i)
{
cin>>a[i].u>>a[i].v>>a[i].w;
}
sort(a+1,a+1+m,cmp);
for(int i=1;i<=m;++i)
{
int js=0;
for(int j=a[i].u;j<=a[i].v;++j)
{
if(used[j]) js++;
}
if(js>=a[i].w) continue;
for(int j=a[i].v;j>=a[i].u;--j)
{
if(!used[j])
{
used[j]=1;
js++;
ans++;
if(js==a[i].w) break;
}
}
}
cout<<ans;
return 0;
}