《P3143 [USACO16OPEN] Diamond Collector S》
题目描述
奶牛 Bessie 一直喜欢闪闪发光的物体,她最近在业余时间开始了一项爱好——挖掘钻石!她收集了 N 颗大小各不相同的钻石(N≤50,000),并希望将它们中的一部分放在谷仓里的两个展示柜中展示。
由于 Bessie 希望每个展示柜中的钻石大小相对接近,她决定如果两颗钻石的大小相差超过 K,就不能将它们放在同一个展示柜中(如果两颗钻石的大小相差恰好为 K,则可以将它们一起展示在同一个展示柜中)。给定 K,请帮助 Bessie 确定她可以在两个展示柜中一起展示的最大钻石数量。
输入格式
输入文件的第一行包含 N 和 K(0≤K≤1,000,000,000)。
接下来的 N 行每行包含一个整数,表示一颗钻石的大小。所有钻石的大小均为正数且不超过 1,000,000,000。
输出格式
输出一个正整数,表示 Bessie 可以在两个展示柜中一起展示的最大钻石数量。
显示翻译
题意翻译
输入输出样例
输入 #1复制
7 3 10 5 1 12 9 5 14
输出 #1复制
5
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int N = 50010;
int n, k;
int a[N];
int left_max[N];
int main() {
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
// 对钻石按大小进行升序排序
sort(a, a + n);
// 计算每个钻石作为左端点时,单展示柜的最大钻石数量
int right = 0;
for (int left = 0; left < n; left++) {
while (right < n && a[right] - a[left] <= k) {
right++;
}
left_max[left] = right - left;
}
// 找出两个不重叠的最大单展示柜组合
int ans = 0;
for (int i = 0; i < n; i++) {
int first_case = left_max[i];
int second_case = 0;
for (int j = i + first_case; j < n; j++) {
second_case = max(second_case, left_max[j]);
}
ans = max(ans, first_case + second_case);
}
cout << ans;
return 0;
}