因为:
每两颗树之间只有一个空位,所以我们从两边向中间遍历,每次只要能放开就贪心放即可。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int n,f[N];
struct node{
int x,h;
bool operator<(const node& t)const{
return x<t.x;
}
}a[N];
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%lld%lld",&x,&y);
a[i]={x,y};
}
sort(a+1,a+n+1);
int i,j,res=0;
for(i=1,j=n;i<=j;i++,j--){
if(i>j) break;
if(i==j){
if(i==1) f[i]=-1;
else{
if(f[i-1]==0||f[i-1]==-1){
if(a[i].x-a[i].h>a[i-1].x) f[i]=-1;
else{
if(i==n) f[i]=1;
else{
if(f[i+1]==0||f[i+1]==1){
if(a[i].x+a[i].h<a[i+1].x) f[i]=1;
}
else if(f[i+1]==-1){
if(a[i].x+a[i].h<a[i+1].x-a[i+1].h) f[i]=1;
}
}
}
}
else if(f[i-1]==1){
if(a[i].x-a[i].h>a[i-1].x+a[i-1].h) f[i]=-1;
else{
if(i==n) f[i]=1;
else{
if(f[i+1]==0||f[i+1]==1){
if(a[i].x+a[i].h<a[i+1].x) f[i]=1;
}
else if(f[i+1]==-1){
if(a[i].x+a[i].h<a[i+1].x-a[i+1].h) f[i]=1;
}
}
}
}
}
}
else{
if(i==1) f[i]=-1;
else{
if(f[i-1]==0||f[i-1]==-1){
if(a[i].x-a[i].h>a[i-1].x) f[i]=-1;
else{
if(i==n) f[i]=1;
else{
if(f[i+1]==0||f[i+1]==1){
if(a[i].x+a[i].h<a[i+1].x) f[i]=1;
}
else if(f[i+1]==-1){
if(a[i].x+a[i].h<a[i+1].x-a[i+1].h) f[i]=1;
}
}
}
}
else if(f[i-1]==1){
if(a[i].x-a[i].h>a[i-1].x+a[i-1].h) f[i]=-1;
else{
if(i==n) f[i]=1;
else{
if(f[i+1]==0||f[i+1]==1){
if(a[i].x+a[i].h<a[i+1].x) f[i]=1;
}
else if(f[i+1]==-1){
if(a[i].x+a[i].h<a[i+1].x-a[i+1].h) f[i]=1;
}
}
}
}
}
if(j==n) f[j]=1;
else{
if(f[j+1]==0||f[j+1]==1){
if(a[j].x+a[j].h<a[j+1].x) f[j]=1;
else{
if(j==n) f[j]=-1;
else{
if(f[j-1]==0||f[j-1]==-1){
if(a[j].x-a[j].h>a[j-1].x) f[j]=-1;
}
else if(f[j-1]==1){
if(a[j].x-a[j].h>a[j-1].x+a[j-1].h) f[j]=-1;
}
}
}
}
else if(f[j+1]==-1){
if(a[j].x+a[j].h<a[j+1].x-a[j+1].h) f[j]=1;
else{
if(j==n) f[j]=-1;
else{
if(f[j-1]==0||f[j-1]==-1){
if(a[j].x-a[j].h>a[j-1].x) f[j]=-1;
}
else if(f[j-1]==1){
if(a[j].x-a[j].h>a[j-1].x+a[j-1].h) f[j]=-1;
}
}
}
}
}
}
}
for(int i=1;i<=n;i++) if(f[i]!=0){
res++;
}
cout<<res;
return 0;
}