看到这题可能我们就知道应该是贪心了,但是关键是以什么为标准进行贪心,最开始写的时候,我是将其按照结束点从小到大的顺序进行排列,然后从最小的开始进行分割,如果此分割内在其之后的点可以被分割到则跳过,但是写的过程中就觉得这样贪心可能会有问题,果不其然,最后只过了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;
}