这题虽然简单,但思路很好。
首先肯定研究一下这个条件,尝试发现一些结论。
容易想到,若i<j<k,i 到
这样问题就转化成,求一个从左到右的最长路。其中相邻点 i<j 满足 xi−xj≥wi+wj。
分析到这里已经可以做了,直接 DP ,用树状数组优化一下,可以一个 log。
但是再分析一下,观察相邻点的限制,发现这个问题还等价于,给一些线段 (wi−xi,wi+xi),选最多的线段互不相交。
经典问题直接贪心,变得更简单了。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=400005;
struct data{
int x,y;
bool operator < (const data &B)const{
return x<B.x;
}
} a[maxn];
int n,x[maxn],w[maxn],ans;
int main(){
freopen("D.in","r",stdin);
freopen("D.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&w[i]), a[i].y=x[i]+w[i], a[i].x=x[i]-w[i];
sort(a+1,a+1+n);
a[0].x=a[0].y=-2e9;
for(int i=1,lst=0;i<=n;i++){
if(a[lst].y<=a[i].x) ans++, lst=i; else
if(a[i].y<a[lst].y) lst=i;
}
printf("%d\n",ans);
return 0;
}