切长条--如何去贪心

在这里插入图片描述
看到这题可能我们就知道应该是贪心了,但是关键是以什么为标准进行贪心,最开始写的时候,我是将其按照结束点从小到大的顺序进行排列,然后从最小的开始进行分割,如果此分割内在其之后的点可以被分割到则跳过,但是写的过程中就觉得这样贪心可能会有问题,果不其然,最后只过了1个测试点.
那到底以什么为标准进行贪心才合理呢?
参考过题解后得知,以起始点从小到大才对,为什么这么说呢,不妨看下下面这个图.
在这里插入图片描述
按起始点从小到大排好队后,依次遍历,每次遍历记录当前最小结束点(一定不能直接以当前遍历节点的结束点为最小结束点,比如上图中即使遍历到5,3仍然是最小结束点),如果出现某一起始点>=该最小结束点,则需要进行一次切割.以上图为例,当遍历到6时,最小结束点为3,而3的结束点已经小于6的起始点了,(需要注意的是,即使是等于也需要进行一次切割).
最后遍历完,输出时还需要加一次,因为最后一个序列并没有切割.

using namespace std;
#include<bits/stdc++.h>
struct node{
    int s,e,l;
}a[32000];
int n;

bool cmp(node a,node b){
    return a.s<b.s;
}

int main(){
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i].s>>a[i].l;
        a[i].e=a[i].s+a[i].l;
    }
    sort(a,a+n,cmp);
    int sum=0,minn;
    minn=a[0].e;
    for(int i=1;i<n;i++)
    {
        minn=min(minn,a[i].e); //important
        if(minn<=a[i].s) //<=
        {
            sum++;
            minn=a[i].e;
        }
    }
    cout<<sum+1; //+1
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值