地址:​https://www.luogu.com.cn/problem/P2082

解析:

刚开始自己写的代码:

我对L递增排列,L相等按R递增排列。

直接逐个判断,相交,或者不相交。

但让每一个区间只和它前一个区间发生关系,显然是错误的。

比如:

[1,5]

[2,4]

[3,6]

答案应该是6,但是我这个代码输出的是7,原因是第三个区间[3,6]与[2,4]发生了关系,但是[1,5]已经把[2,4]覆盖了。

#include<cstdio>//WAWAWAWAWAWA!
#include<stack>
#include<map>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+20;
struct node
{
ll l,r;
}st[maxn];
bool cmp(node a , node b)
{
if(a.l==b.l)
return a.r<b.r;
return a.l<b.l;
}
int main()
{ // 4 0 20
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>st[i].l>>st[i].r;
}
ll sum=0;
sort(st+1,st+1+n,cmp);
sum=st[1].r-st[1].l+1;
for(int i=2;i<=n;i++)
{
if(st[i].r>st[i-1].r)
{
if(st[i].l>st[i-1].r)
sum+=st[i].r-st[i].l+1;
else
sum+=st[i].r-st[i-1].r;
}
}
cout<<sum<<endl;
}

正确的贪心思路:

因为首要排序的是L,所以这个情况下R基本是乱序的。

下一个区间需要算的前提是什么?当然是超出之前所有区间的范围了。

所以可以维护一个最大r,只有当前的区间超越r,才能纳入计算(其实自己算也是这个思想的,脑袋秀逗了)。

同时更新最大的r。
引以为戒~

AC代码:

#include<cstdio>
#include<stack>
#include<map>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+20;
struct node
{
ll l,r;
}st[maxn];
bool cmp(node a , node b)
{
if(a.l==b.l)
return a.r<b.r;
return a.l<b.l;
}
int main()
{ // 4 0 20
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>st[i].l>>st[i].r;
}
ll sum=0;
sort(st+1,st+1+n,cmp);
sum=st[1].r-st[1].l+1;
ll r=st[1].r;
for(int i=2;i<=n;i++)
{
if(st[i].l>r)
{
sum+=st[i].r-st[i].l+1;
r=st[i].r;
}
else if(st[i].r>r)
{
sum+=st[i].r-r;
}
r=max(r,st[i].r);
}
cout<<sum<<endl;
}