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 }
原文地址:https://www.cnblogs.com/Leohh/p/7654883.html