BZOJ 4582 [Usaco2016 Open]Diamond Collector:贪心【相差不超过k】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4582
题意:
给你n个数。
让你将其中的一些数放入两个不同的集合中,并保证同一集合内两两元素相差不超过k。
问你两个集合中数字个数之和最大为多少。
题解:
贪心。
先将所有数字升序排序。
然后O(N)处理出ans[i]:
以i为起点,在一个集合中,往后最多能选多少个数。
再从后往前更新ans[i]和best:
以i以及i后面的点为起点,在一个集合中,往后最多能选多少个数。
ans[i] = max(ans[i], ans[i+1])
同时更新答案:best = max ans[i] + ans[i+ans[i]]
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #define MAX_N 50005 6 7 using namespace std; 8 9 int n,k; 10 int best=0; 11 int a[MAX_N]; 12 int ans[MAX_N]; 13 14 void read() 15 { 16 cin>>n>>k; 17 for(int i=0;i<n;i++) 18 { 19 cin>>a[i]; 20 } 21 } 22 23 void solve() 24 { 25 sort(a,a+n); 26 int pos=0; 27 for(int i=0;i<n;i++) 28 { 29 while(a[pos]-a[i]<=k && pos<n) pos++; 30 ans[i]=pos-i; 31 } 32 ans[n]=0; 33 for(int i=n-1;i>=0;i--) 34 { 35 best=max(best,ans[i]+ans[i+ans[i]]); 36 ans[i]=max(ans[i],ans[i+1]); 37 } 38 } 39 40 void print() 41 { 42 cout<<best<<endl; 43 } 44 45 int main() 46 { 47 read(); 48 solve(); 49 print(); 50 }