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;
} 
posted @ 2018-12-07 15:11  ChunhaoMo  阅读(140)  评论(0编辑  收藏  举报