P1250 种树 [贪心:区间选点问题]

https://www.luogu.com.cn/problem/P1250


贪心,排序,差分约束
黄色题

 

思路一:  区间选点问题
贪心,要种树种得少,就要使一棵树给多个区间使用,这样,尽量在重叠区间种树即可,而重叠位置一定是区间尾部。处理问题时,先按所有区间的结束位置从小到大排序,若结束位置相同,则按开始位置从大到小排序。之后依次处理每个区间,先在第一个区间尾部种满足要求的树,对下一个区间,看差多少棵就在该区间尾部种多少。

步骤:

①先按照b[]从小到大快排

②对每个区间依次处理

a.从前到后扫描这个区间,统计点的个数;

b.若没有超过要求的点数,则从该区间后向前扫描,添加覆盖点。

③输出ans

#include<bits/stdc++.h>
using namespace std;
int n,h,k,flag[30005],ans;
struct node{
    int s,e,t;
}a[30005];
bool cmp(node a,node b)
{
    return a.e<b.e; //这里要注意按区间尾部从小到大排序,因为要保证两个区间尾部不重叠
}
int main()
{
    cin>>n>>h;
    for(int i=1; i<=h; i++)
    {
        cin>>a[i].s>>a[i].e>>a[i].t;
    }
    sort(a+1,a+h+1,cmp);
    for(int i=1; i<=h; i++)
    {
        k=0;
        for(int j=a[i].s; j<=a[i].e; j++)
        {
            if(flag[j])
            {
                k++;
            }
        }
        if(k<a[i].t)
        {
            for(int j=a[i].e; j>=a[i].s; j--)
            {
                if(!flag[j])
                {
                    flag[j]=1;
                    k++;
                    ans++;
                    if(k==a[i].t)
                    {
                        break;
                    }
                }
            }
        }
    }
    cout<<ans;
}

思路二:差分约束

posted @ 2022-08-09 14:05  -イレイナ  阅读(78)  评论(0)    收藏  举报