Codeforces 985C Liebig's Barrels

C. 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 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
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个数,要分成n组,保证n组中每一组的最小组彼此之差的绝对值不大于l,求这n个最小值和的最大值

思路:贪心,首先把数组排序,最保险的情况就是前n个数是这n个最小值,但是这样不能保证最优。然后怎么才能更大一点呢,就是让最大的最小值再大一点,第一个最小值肯定是第一个数,需要找到离它不超过l的最远的数然后先,正向贪心(因为最小的会拉低和的最大值,所以尽量让小的连在一起,然后再反向贪心,它是作为它及它之后的数的最小值)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
ll a[maxn],b[maxn];
   int n,k,l;

int main()
{
    cin>>n>>k>>l;
    ll sum = 0;
    for(int i = 1; i <= n * k; i++)
    {
        cin>>a[i];
    }
    sort(a + 1,a + n * k + 1);
    if(a[n] - a[1] <= l)
    {
       int m,cnt = 0;

       ll sum = 0;
       for(int i = 1; i <= n * k; i += k)
       {
           if(a[i] - a[1] <= l)
           {
              cnt++;
              sum += a[i];
              b[i] = 1;
           }

       }
       if(cnt == n)
       {
           cout<<sum<<endl;
       }
       else
       {
            for(int i = 1; i <= n * k; i++)
       {
           if(a[i] - a[1] > l)
           {
              m = i - 1;
              break;
           }
       }
           for(int i = m; i >= 1; i--)
           {
               if(!b[i])
               {
                   sum += a[i];
                   cnt++;
               }
               if(cnt == n)
                break;
           }
           cout<<sum<<endl;
       }
    }
    else
        cout<<0<<endl;

    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值