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;
}
posted @ 2018-07-22 16:05  Monster_Qi  阅读(212)  评论(0编辑  收藏  举报