1423:【例题2】种树

1423:【例题2】种树

题解

【思路点拨】
       首先按照区间的结束位置从小到大排序。然后从区间1到区间n进行选择:对于当前区间,若集合中的数不能覆盖它,则将区间末尾的数加入集合


  贪心策略:取最后一个。

       

        种树要种得少,就要使一棵树给多个区间使用。这样,尽量在重叠区间种树即可,而重叠位置一定是在区间尾部。

        处理问题时,先按所有区间的结束位置排序,之后依次处理每个区间,先在第一个区间尾部种满足要求的树,对下一个区间,看差多少棵就在该区间尾部种多少

 

代码

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>

using namespace std;

int n,m,ans=0,t,k=0;
bool vis[50000];
struct app
{
    int s,e,v;
}a[5005];

bool cmp(app x,app y)
{
    return x.e <y.e ;
}

int main()
{
    memset(vis,0,sizeof(vis));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
      scanf("%d%d%d",&a[i].s ,&a[i].e ,&a[i].v );
    
    sort(a+1,a+m+1,cmp);
    
    for(int i=1;i<=m;i++)
    {
        k=0;
        for(int j=a[i].s ;j<=a[i].e ;j++)   //遍历种了多少树
         if(vis[j]) k++;
        
        if(k>=a[i].v )  continue;   //该区间树已种够
        else
        {
            for(int z=a[i].e ;z>=a[i].s;z--)   //从区间后面往前补
            {
                if(!vis[z])
                {
                    k++;  
                    ans++;
                    vis[z]=1;
                    if(k>=a[i].v ) break;    //补够即停
                }
                
            }
        }
    }
    
    printf("%d",ans);
    
    return 0;
}

 

posted @ 2019-06-08 14:23  晔子  阅读(707)  评论(0编辑  收藏  举报