cf985C Educational Round 44 Div2-C【贪心】

Date:2021.12.31

题意:有m=n*k个板子,每个桶需要k个板子构成,且构成的桶体积为k个板子里最短的那个。且给定一个l,桶与桶之间体积差的绝对值不超过l,求构造出的n个桶的总体积最小是多少。

思路:开始想了半天不知道怎么贪心,看了题解搞明白了,我们只需要找到n个最短板。首先排序,upper_bound找到最大的最短板(即从左向右>=a[0]+l的最后一个元素的下标x),我们要让n个尽可能小的一堆,因此要从第一个元素每次+k直到>x,这时>x的元素一定不可以作为最短板,因此要从x向前找没用做过最短板的,直到找到n个最短板,这样一定最大。
代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long LL;
LL t,n,m,k;LL l;
bool st[N];
LL a[N];
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    cin>>n>>k>>l;
    for(int i=0;i<n*k;i++) cin>>a[i];
    sort(a,a+n*k);
    if(a[n-1]-a[0]>l) {cout<<'0'<<endl;return 0;}
    LL x=upper_bound(a,a+n*k,a[0]+l)-a-1;
    LL sum=0,cnt=0;
    for(int i=0;i<=x;i+=k) 
        if(cnt<n)
        {cnt++;sum+=a[i];st[i]=true;}
    for(int i=x;i>=0;i--)
        if(!st[i]&&cnt<n) {cnt++;sum+=a[i];st[i]=true;}
    cout<<sum;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值