标签:
题意:给你一个xi,wi的点集合 ,问你其中最大的子集满足|xi - xj| >= wi + wj 的大小是多少。
解题思路:dp+离散化+树状数组。把它看成是 一条边[xi-wi,xi+wi] 去覆盖区域就行了
解题代码:
1 // File Name: d.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月18日 星期三 15时28分50秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 #define maxn 700000 28 int lowbit(int x) 29 { 30 return x &(-x); 31 } 32 int tree[maxn]; 33 int getsum(int x) 34 { 35 int sum = 0; 36 while(x >= 1) 37 { 38 sum = max(tree[x],sum); 39 x -= lowbit(x); 40 } 41 return sum; 42 } 43 int n,m,tt; 44 void update(int k ,int v) 45 { 46 while(k <= tt) 47 { 48 tree[k] = max(tree[k],v); 49 k += lowbit(k); 50 } 51 } 52 struct node{ 53 int x ,l , r; 54 }qu[maxn]; 55 int cmp(int x, int y) 56 { 57 return x < y ; 58 } 59 int nodecmp(node x, node y) 60 { 61 return x.x < y.x; 62 } 63 map<int ,int > mp; 64 int ch[maxn]; 65 int main(){ 66 m = 0 ; 67 scanf("%d",&n); 68 int tm; 69 for(int i = 1;i <= n;i ++) 70 { 71 scanf("%d %d",&qu[i].x,&tm); 72 qu[i].l = qu[i].x - tm; 73 qu[i].r = qu[i].x + tm; 74 ch[m+1] = qu[i].l; 75 ch[m+2] = qu[i].r; 76 m += 2; 77 } 78 sort(qu+1,qu+1+n,nodecmp); 79 sort(ch+1,ch+1+m,cmp); 80 ch[0] = -1e9- 1000; 81 tt = 0 ; 82 for(int i =1 ;i <= m;i ++) 83 { 84 if(ch[i] != ch[i-1]) 85 { 86 tt ++ ; 87 mp[ch[i]] = tt; 88 } 89 } 90 int ans = 0 ; 91 for(int i = 1;i <= n;i ++) 92 { 93 int l = mp[qu[i].l]; 94 ans = getsum(l); 95 //printf("%d %d %I64d\n",l,mp[qu[i].r],getsum(l)); 96 update(mp[qu[i].r],ans +1); 97 } 98 ans = getsum(tt); 99 printf("%d\n",ans); 100 return 0; 101 }
Codeforces 527D Clique Problem
标签:
原文地址:http://www.cnblogs.com/zyue/p/4348333.html