loj #10001. 「一本通 1.1 例 2」种树
解题思路
贪心,首先按右端点排序,然后从小往大扫,因为要求树最少,所以要尽量放在右端点。然后开个bool数组判断是否种过树即可。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 3e4+5;
inline int rd(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='0') f=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,h,ans,sum[MAXN];
bool vis[MAXN];
struct Tree{
int st,ed,k;
}t[MAXN];
inline bool cmp(Tree A,Tree B){
if(A.ed==B.ed) return A.st<B.st;
return A.ed<B.ed;
}
int main(){
n=rd();h=rd();
for(register int i=1;i<=h;i++)
t[i].st=rd(),t[i].ed=rd(),t[i].k=rd();
sort(t+1,t+1+h,cmp);
int last=0,now=0;
for(register int i=1;i<=h;i++){
for(register int j=t[i].st;j<=t[i].ed;j++)
if(vis[j]) t[i].k--;
if(t[i].k<=0) continue;
ans+=t[i].k;
int cnt=0;
for(register int j=t[i].ed;;j--){
if(!vis[j]) vis[j]=1,cnt++;
if(cnt==t[i].k) break;
}
}
printf("%d",ans);
return 0;
}