zoukankan      html  css  js  c++  java
  • CF985C

    CF985C

    题意:

    你要组成N个木桶,组成每个木桶需要K个木块,(第二行给你N*K个木块),使得任意两个木桶之间的差值不超过L的情况,使得所有木桶可以装的水的和最大,输出这个最大和,如果无法满足要求输出0。

    解法:

    因为众所周知的木板原理,我们考虑贪心,对木板的长度进行排序。
    易知,让长度相差小的木板组合比较优。
    首先考虑没答案的情况,假设最短的木板为a[0],那么所有木桶中能装水的最小值就确定了为a[0]。所以其他木桶的最短板不能超过a[0]+L,如果范围在a[0]~(a[0]+L)的木板少于N块肯定不行
    排序upper_bound求一下即可,假设有pos块。
    如满足要求,考虑范围在a[0]~(a[0]+L)木块,我们尽量的使短的木板组合在一起,那么就是[0,k)个组成第一个桶(如果剩余木板还够N-1个),前[K,2k)个组成第二个桶(如果剩余木板还够N-2个)...前[iK,(i+1)*k)个组成第i个桶(如果剩余木板还够N-i个)。如果选取了i个之后,剩余不够再这样组合了,我们直接从这些木块中选取最后的 N-i 块即可。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    
    using namespace std;
    
    #define LL long long
    #define N 100010
    
    int m,n,k,l,a[N];
    
    int main() {
        scanf("%d%d%d",&n,&k,&l);
        m = n * k;
        for(int i = 0 ; i < m ; i++)
            scanf("%d",&a[i]);
        sort(a,a + m);
        int pos = upper_bound(a,a + m,a[0] + l) - a;
        LL ans = 0;
        if(n <= pos) {
            int i;
            for(i = 0 ; pos - i * k > n - i ; i++) ans += a[i * k];
            for(int j = pos - 1 ; j >= pos - n + i ; j--) ans += a[j];
        }
        printf("%lld 
    ",ans);
    //    system("pause");
        return 0;
    }
    
  • 相关阅读:
    oracle用户被锁
    Docker入门
    物化视图
    MySQL报错:Packets larger than max_allowed_packet are not all
    ORA-01555 快照过旧
    mysql授予权限
    CentOS7.4安装部署KVM虚拟机
    前端面试题收藏
    CoffeeScript 学习笔记
    spring学习笔记(四)
  • 原文地址:https://www.cnblogs.com/Repulser/p/11385812.html
Copyright © 2011-2022 走看看