D - Liebig's Barrels CodeForces - 985C

C. Liebig’s Barrels
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard 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 n, k 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
inputCopy
4 2 1
2 2 1 2 3 2 2 3
outputCopy
7
inputCopy
2 1 0
10 10
outputCopy
20
inputCopy
1 2 1
5 2
outputCopy
2
inputCopy
3 2 1
1 2 3 4 5 6
outputCopy
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.

题意:给你一些木板,k个木板可以组成一个木桶,体积为木桶最短的那个木板的长度,每个桶的体积不能相差超过l,问你可以组成的最大体积和为多少,如果不能组成输出0

思路:先小到大排序,然后找出小于第一个加l 的有多少个,因为第一个必要用到,所以贪心只能在满足<=a[0]+l的木板里进行。
接下来,直接扩展木板就可以了,就是让最短的木板尽可能的大

#include<bits/stdc++.h>
#define LL long long
#define Max 100005
const LL mod=1e9+7;
const LL LL_MAX=9223372036854775807;
using namespace std;
LL n,k,l;
LL a[Max];
priority_queue<LL ,vector<LL> ,greater<LL> >p;
int main()
{
    scanf("%lld%lld%lld",&n,&k,&l);
    LL x;
    for(int i=0;i<n*k;i++){
        scanf("%lld",&a[i]);
        p.push(a[i]);
    }
    sort(a,a+(n*k));
    LL ans=0,mn=p.top();
    int t=0;
    while(p.size()){
        if(p.top()>(mn+l))//找有多少个小于a[0]+l的木板
            break;
        t++;
        p.pop();
    }
    if(t<n){//如果小于a[0]+l的不足n个,很明显不满足条件
        printf("0\n");
        return 0;
    }
    int now = 0;
    for(int i=0;i<n;i++){
        ans+=a[now++];
        for(int j=0;j<k-1;j++){//扩张木板
            if(t-now > n-i-1)
                now++;
            else
                break;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Gee_Zer/article/details/89330137
今日推荐