CodeForces-985C Liebig's Barrels
CodeForces-985C Liebig's Barrels
Description
You have m = n·k wooden staves. The i-th stave has length \(a_i\). You have to assemble n barrels consisting of k staves each, you can use any k staves to construct a barrel. Each stave must belong to exactly one barrel.
Let volume \(v_j\) of barrel j be equal to the length of the minimal stave in it.
You want to assemble exactly n barrels with the maximal total sum of volumes. But you have to make them equal enough, so a difference between volumes of any pair of the resulting barrels must not exceed l, i.e. \(|v_x - v_y| ≤ l\) for any 1 ≤ x ≤ n and 1 ≤ y ≤ n.
Print maximal total sum of volumes of equal enough barrels or 0 if it's impossible to satisfy the condition above.
Input
The first line contains three space-separated integers n, k and l \((1 ≤ n, k ≤ 10^5, 1 ≤ n·k ≤ 10^5, 0 ≤ l ≤ 10^9).\)
The second line contains m = n·k space-separated integers$ a_1, a_2, ..., a_m$ (1 ≤ $a_i $ ≤ 109) — lengths of staves.
Output
Print single integer — maximal total sum of the volumes of barrels or 0 if it's impossible to construct exactly n barrels satisfying the condition $|v_x - v_y| ≤ l $for any 1 ≤ x ≤ n and 1 ≤ y ≤ n.
Examples
Input
4 2 1
2 2 1 2 3 2 2 3
Output
7
Input
2 1 0
10 10
Output
20
Input
1 2 1
5 2
Output
2
Input
3 2 1
1 2 3 4 5 6
Output
0
Note
In the first example you can form the following barrels: [1, 2], [2, 2], [2, 3], [2, 3].
In the second example you can form the following barrels: [10], [10].
In the third example you can form the following barrels: [2, 5].
In the fourth example difference between volumes of barrels in any partition is at least 2 so it is impossible to make barrels equal enough.
题意
给你n*k个木板,组成n个桶,每个桶需要k个木板,每个桶的容积由长度最短的木板决定,即为长度最短的木板的长度。n个桶要满足任意两个桶的容积差的绝对值不超过\(l\)。如果不可能输出0,可能输出最大的木桶容积总和
题解
这个题重点在于如何贪心是正确的,首先我们比较容易想到先对木板长度从小到大排序,从前往后扫描一遍,找到第一个比\(a_1+l\)大的\(a_{split}\),它包括它后面的木板都必须和前面的木板结合构成木桶才能满足条件,显然当\(a_{n}-a_1>l\)时不可能满足条件,此时输出0,其他时候均可满足条件。
我们只需考虑怎样让容积最大即可。显然\(a_i\)后面的木板长度大小都无所谓因为它们决定不了容积,那我们就考虑让后面的木板选k-1个,前面的最靠近\(a_{split}\)的选1个来构成木桶,这样最大程度的让前面大长度的木板决定容积,当后面不够k-1个的时候终止选择。
然后我们从\(a_1\)到最后一个没被选择的木板循环,选择相邻的k个作为一个木桶,这样能保证小木板尽量与小木板结合从而使容积最大,最后不够k个时即相当于选择了后面不够k-1的木板和前面不够k个木板结合成木桶,这样即保证了容积最大。
AC代码:
#include <bits/stdc++.h>
#define maxn 100050
using namespace std;
long long a[maxn];
int main() {
int n, k, l;
scanf("%d%d%d", &n, &k, &l);
for (int i = 1; i <= n * k; i++) {
scanf("%d", &a[i]);
}
sort(a + 1, a + n * k + 1);
int minv = a[1];
int split;
for (split = 1; split <= n * k; split++) {
if (a[split] > minv + l) {
break;
}
}
int cnt1 = split - 1, cnt2 = n * k - split + 1;
int begin1 = 1;
long long sum = 0;
while (cnt2) {
if (cnt2 < k - 1) {
break;
}
else if (cnt2 >= k - 1) {
sum += a[cnt1];
cnt2 = cnt2 - k + 1;
cnt1--;
}
if (cnt1 <= 0) break;
}
if (cnt1 <= 0 && cnt2 > 0) {
cout << 0 << endl;
return 0;
}
else {
for (int i = 1; i <= cnt1; i += k) {
sum += a[i];
}
cout << sum << endl;
}
return 0;
}