C. Liebig's Barrels
链接
[https://codeforces.com/contest/985/problem/C]
题意
给你n,k,l,分别表示木桶数,一个木桶所需的 木块数,以及最大最小体积之差不超过l,
根据短板定律,的最大体积和
分析
就是很典型的贪心,先排序二分查找可能的最大的那个体积
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 <iostream>
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+10;
ll a[N];
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//freopen("in.txt","r",stdin);
ll n,k,l;
while(cin>>n>>k>>l){
for(int i=1;i<=n*k;i++)
cin>>a[i];
sort(a+1,a+n*k+1);
if(a[n]-a[1]>l) {
cout<<0<<endl; continue;
}
else {
ll sum=0;//非常经典的贪心
ll h=a[1]+l;
int p=((upper_bound(a+1,a+n*k+1,h))-a)-1;//最大的可能体积
int cnt=0,q=p;
for(int j=n*k;j-(k-1)>p;j-=(k-1)){//从p后面找出(k-1)个使得尽量大
sum+=a[q--]; cnt++;
}
for(int i=1;i<=p-cnt;i+=k)//从前面开始找
sum+=a[i];
cout<<sum<<endl;
}
}
return 0;
}