zoukankan      html  css  js  c++  java
  • CF985C Liebig's Barrels 贪心 第二十

    Liebig's Barrels
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    You have m = n·k wooden staves. The i-th stave has length ai. 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 vj 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. |vx - vy| ≤ 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 nk and l (1 ≤ n, k ≤ 105, 1 ≤ n·k ≤ 105, 0 ≤ l ≤ 109).

    The second line contains m = n·k space-separated integers a1, a2, ..., am (1 ≤ ai ≤ 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 |vx - vy| ≤ l for any 1 ≤ x ≤ n and 1 ≤ y ≤ n.

    Examples
    input
    Copy
    4 2 1
    2 2 1 2 3 2 2 3
    output
    Copy
    7
    input
    Copy
    2 1 0
    10 10
    output
    Copy
    20
    input
    Copy
    1 2 1
    5 2
    output
    Copy
    2
    input
    Copy
    3 2 1
    1 2 3 4 5 6
    output
    Copy
    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  l    你要做n个桶,每个桶需要k个木板,用木板拼好的桶相互之间体积的差距<=l,桶的体积大小就是最短的那根木板的长度大小。

    第二行 共n*k个数,分别表示n*k个木板的长度。

    开始自己的思路是对的,但是中间的具体细节写错了,wa了好几发

    然后看的别人的博客才写出来的

    http://www.mamicode.com/info-detail-2309549.html

    分析:

    先对边排个序

    不存在的情况,就是a[n]-a[1]>l,那就是不存在,因为要是差距尽可能小,前n小的都分别作为n个桶的一块木板,那么这之中最大的差距就是a[n]-a[1],要是a[n]-a[1]都满足条件(<=l)了,那就满足条件了。

    其次,要使体积和最大输出体积和,我毛想想觉得s=a[1]+……a[n],结果WA了,引起了我的深思。

    因为:

    eg:4    3    17

    1   2   3   5   9   13  18  21  22  23  25 26

    它可以这样组3组:

    18  25  26

    13   22  23

    1     2     3

    5     9   21

    这样体积为1+5+13+18=37,不是简单地1 +2 +3 +5=11

    所以我的思路:先要找到最大的满足条件的数,可以用二分找更快,在这组样例中,是18,它-a[1]<=l,

    那么从最后开始去k-1个和18拼,s+=18,再下一个数13(25  26),再从最后找k-1个数(22  23),

    再下一个数9,发现再k-1个数不够了,那就从头开始找了,(1   2   3)一组,在去(5   9  13)时,发现13

    已经被取走,那就s+=5就可以了。

    #include <map>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define debug(a) cout << #a << " " << a << endl
    using namespace std;
    const int maxn = 1e5 + 10;
    const int mod = 1e9 + 7;
    typedef long long ll;
    ll a[maxn];
    int main(){
        std::ios::sync_with_stdio(false);
        ll n, k, m;
        while( cin >> n >> k >> m ) {
            for( ll i = 1; i <= n*k; i ++ ) {
                cin >> a[i];
            }
            sort( a + 1, a + n*k + 1 );
            ll num = -1;
            for( ll i = n*k; i >= n; i -- ) {
                if( a[i] - a[1] <= m ) {
                    num = i;
                    break;
                }
            }
            if( num == -1 ) {
                cout << 0 << endl;
                continue;
            }
            ll sum = 0, j = num, t = 0 ;
            for( ll i = n*k ; i - ( k-1 ) > num; i = i - ( k-1 ) ) {
                sum += a[j--];
                t ++;
            }
            for( ll i = 1; i < num - t + 1; i += k ) {
                sum += a[i];
            }
            cout << sum << endl;
        }
        return 0;
    }
    彼时当年少,莫负好时光。
  • 相关阅读:
    YbtOJ20030 连珠风暴
    YbtOJ20029 最大权值
    P6859 蝴蝶与花
    P4115 Qtree4
    P2486 [SDOI2011]染色
    P2487 [SDOI2011]拦截导弹
    P5163 WD与地图
    P3733 [HAOI2017]八纵八横
    CF1100F Ivan and Burgers
    P1712 [NOI2016]区间
  • 原文地址:https://www.cnblogs.com/l609929321/p/9236056.html
Copyright © 2011-2022 走看看