题意
总共有
m=n×k
m
=
n
×
k
个木板,第
i
i
个木板的长度为 ai,要用这
m
m
个木板做成 n 个桶,每个桶由
k
k
个木板组成,每个桶的容积由构成这个桶的最短木板决定,要求所有的桶的容积差距不能超过 l,问所有桶的最大容积和。
输入
第一行为
3
3
个整数 n,k,l (1≤n,k≤105,1≤n×k≤105,0≤l≤109),第二行为
n×k
n
×
k
个整数
a1,a2,⋯,an×k (1≤ai≤109)
a
1
,
a
2
,
⋯
,
a
n
×
k
(
1
≤
a
i
≤
10
9
)
。
输出
输出所有木桶的最大容积和,如果无法达到要求,则输出
0
0
。
样例
输入 |
4 2 1 2 2 1 2 3 2 2 3 |
输出 |
7 |
提示 |
可以按照这样的方式来造木桶:[1,2],[2,2],[2,3],[2,3]。
输入 |
---|
2 1 0 10 10 | 输出 | 20 | 提示 | 可以按照这样的方式来造木桶:
[10],[10]
[
10
]
,
[
10
]
|
输入 |
---|
1 2 1 5 2 | 输出 | 2 | 提示 | 可以按照这样的方式来造木桶:
[2,5]
[
2
,
5
]
。 |
输入 |
---|
3 2 1 1 2 3 4 5 6 | 输出 | 0 | 提示 | 无论如何造木桶,任意两个木桶之间最大差距的最小值为
2
2
,无法达到要求。 |
题解
由于最短的木板一定是其中某个木桶的容积,所以先将与最短的板长度差小于等于 l 的放到一起从小到大排序,每
k
k
个板构成一个桶,且保证剩下的板子足够构成 n 个桶,这样贪心下去,就能得到答案。 过题代码 #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
#define LL long long
const int maxn = 100000 + 100;
int n, k, l;
LL ans;
int *it;
int num[maxn];
priority_queue<int, vector<int>, greater<int> > que;
int main() {
#ifdef LOCAL
freopen("test.txt", "r", stdin);
#endif
ios::sync_with_stdio(false);
while(scanf("%d%d%d", &n, &k, &l) != EOF) {
ans = 0;
for(int i = 0; i < n * k; ++i) {
scanf("%d", &num[i]);
}
sort(num, num + n * k);
it = upper_bound(num, num + n * k, num[0] + l);
int cnt = it - num;
if(cnt < n) {
printf("0\n");
continue;
}
int Index = 0;
int Chose = 0;
int Left = cnt;
while(Index < cnt) {
ans += num[Index];
++Chose;
for(int i = 0; i < k; ++i) {
++Index;
--Left;
if(n - Chose >= Left) {
break;
}
}
}
printf("%I64d\n", ans);
}
return 0;
}
|