emmmm...
做了半天 发现自己就是个大sb。
题意: 给你n*k个木版,每次选择k个木版,组成n个桶,然后每个桶的体积V等于组成桶的k个木版中最短的那个木版。然后
要求 V1 V2 V3 。。。Vn 任意两个做差的绝对值小于等于l
如果没有满足条件的 输出0
否则 输出 n个桶最大的体积和
思路:
首先,我们去判断能不能构成n个桶。 也就是说,我们这个时候不考虑体积和最大,将n*k个木板排序,我们现在要做的是判断它能不能组成n个桶,那我们就去取前n个木板 作为每个桶里的一个木版 因为这是排序后的 则这n个桶的体积就是这n个木版的长度,则体积最大的桶的体积等于a[n],体积最小的桶的体积等于a[1]。则只判断a[n] - a[1] 和 l 的关系就好了 如果大于l 输出0。否则,则说明满足条件啦。
好了~ 这里开始举个栗子~ (下面的数据非原创)
4 3 17
1 2 3 5 9 13 18 21 22 23 25 26
这里 18是最大满足构成n个桶的条件。 因为18是最大的减1小于等于17的数字啦。
因为是让总体积和最大啦。
所以我们这样选
(1)18 25 26
(2)13 22 23
(3)1 2 3
(4)5 9 21
这样 总的体积 = 18 + 13 + 1 + 5 = 37
注意我写的选的过程的顺序。 先从18的右边开始找, 当不能找的时候,从最左边找。 这样才能保证最终的n个体积最大啦~~~
// // 985C.cpp // CodeForces // // Created by Terry on 2018/5/27. // Copyright © 2018年 Terry. All rights reserved. // /* 4 3 17 1 2 3 5 9 13 18 21 22 23 25 26 这里 18是最大满足构成n个桶的条件。 因为18是最大的减1小于等于17的数字啦。 因为是让总体积和最大啦。 所以我们这样选 (1)18 25 26 (2)13 22 23 (3)1 2 3 (4)5 9 21 */ #include <stdio.h> #include <iostream> #include <algorithm> using namespace std; const int maxn = 100005; long long int a[maxn]; int main(){ long long n, k, l; scanf("%lld%lld%lld", &n, &k, &l); for(long long i = 1; i <= n * k; i++){ scanf("%lld", &a[i]); } sort(a + 1, a + 1 + n * k); if(a[n] - a[1] > l){ // 判断能不能构成n个水题啦~~~ printf("0\n"); } else{ long long s, p; // 找到那个关键的数字 18 呀 for(int i = n * k; i >= n; i--){ if(a[i] - a[1] <= l){ p = i; break; } } s = 0; // 最终的体积啦 int num = 0; // 记录从标准数向前取了多少 int j = p; for(long long i = n * k; i - (k - 1) > p; i = i - (k - 1)){ s += a[j]; // 18 13 j--; num++; } for(long long i = 1; i < p -num + 1; i = i + k){ s += a[i];// 1 5 } printf("%lld\n", s); } return 0; }