codeforce 985C Liebig's Barrels

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;
}

猜你喜欢

转载自blog.csdn.net/weixin_37686922/article/details/80472081
今日推荐