传送门:点击打开链接
题目大意:
有n个桶,每个桶需要k个木块,现在给你m(m=n*k)个木块,让你把这些桶塞满。现在,假定一个木桶的容积为这个木桶所插木块中最短的一块,任意两个木桶间的容积差距<=l。
问如何组装木桶,使总容积最大。
题目思路:
刚开始看到,哈哈哈,排个序,取前n个木桶就行了呗。。仿佛智障降临,光速wa掉。
然后开始想,如果出现
3 3 5
1 3 3 6 6 6 6 6 6
这种情况,那么3个桶的容积应该为1,6,6。而不是1,3,3。
所以换了个wa法。最后看了正解。记大于a[0]+l的第一个值出现的位置为pos。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
typedef long long ll;
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 200005;
ll n,k,l,m,a[maxn],ans,pos;
vector<ll> e;
int main()
{
cin>>n>>k>>l;
m = n*k;
for(int i=0;i<m;i++)
scanf("%lld",&a[i]);
sort(a,a+m);
ll temp = a[0]+l;
for(int i=0;i<n;i++)
{
e.push_back(a[i]);
}
if(e[e.size()-1]-e[0]>l)
{
cout<<0<<endl;
return 0;
}
e.clear();
pos = m;
for(int i=0;i<m;i++)
{
if(a[i]>temp)
{
pos = i;
break;
}
}
// cout<<pos<<endl;
ans = 0;
int cnt = 0;
for(int i=0;i<n;i++)
{
ans += a[cnt++];
for(int j=0;j<k-1;j++)
{
if(pos-cnt>n-i-1) //pos-cnt表示临界位置与当前位置中间隔了多少个元素,n-i-1表示还剩下多少个木桶
cnt++; //如果隔的元素数量大于剩余木桶数量的话,说明可以往当前木桶里面继续塞小的,而不是塞较大的
else
break;
}
}
cout<<ans<<endl;
return 0;
}
//3 3 5
//1 3 3 6 6 6 6 6 6