codeforces 527D:脑洞题

表示这类题目完全不会

把表达式转化后:

xi+wi<=xj-wj (xi<=xj)

xj+wj<=xi-wi (xi>=xj)

好像还是看不出什么- -||  

满足上式的i j两点就能抱团,那我们要找尽量多的点满足上述关系

其实上述两个式子是等价的(想一想)

所以只需要满足xi+wi<=xj-wj的两个点就能抱团

那我们的策略是贪心,要尽量多的点满足这个式子的话,自然xi+wi越小越好,所以我们按xi+wi排序

这样得到的序列,每一个元素只需要和前一个元素判断一下就好,因为如何i和i-1符合这个式子的话,和之前的点是必然符合的(因为我们是按照xi+wi排序的,之前的点xi+wi肯定小于等于当前点)

#include"cstdio"
#include"queue"
#include"cmath"
#include"stack"
#include"iostream"
#include"algorithm"
#include"cstring"
#include"queue"
#include"map"
#include"vector"
#define ll long long
#define mems(a,b) memset(a,b,sizeof(a))
#define ls pos<<1
#define rs pos<<1|1

using namespace std;
const int MAXN = 200500;
const int MAXE = 200500;
const int INF = 0x3f3f3f3f;

struct nn{
    int w,x;
}node[MAXN];

bool cmp(nn a,nn b){
    return a.x+a.w<b.w+b.x;
}

int main(){
    int n;scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d",&node[i].x,&node[i].w);
    sort(node,node+n,cmp);
    int ans=1;
    int t=node[0].x+node[0].w;
    for(int i=1;i<n;i++){
        if(node[i].x-node[i].w>=t){
            ans++;
            t=node[i].x+node[i].w;
        }
    }
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/luxiaoming/p/5137642.html