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; }