Educational Codeforces Round 44 (Rated for Div. 2) C - Liebig's Barrels —— 思维

题目链接:http://codeforces.com/contest/985/problem/C
很简单的一道题目,但是想了半天还把自己气得要死,因为又读错题意了。。
题意:
给你3个数,n,k, l ,再给你n*k的a[],表示叫你凑n个木桶出来,木桶的长度取决于最小的a,最终的n个木桶最大和最小的差值不超过 l ,问这些木桶长度加起来最长有多少。
那么我们先排个序,如果第n个数和第1个数的差值都大于 l 了,那么就是不可能的。之后要分是不是1的情况,为什么要分情况呢?接下来会讲到。
sort完之后我们for一遍看看能与a[1]相距 l 的最大的位置在哪里。记做cnt,那么我们的任务是在这cnt个数里面取出合法且最大的n个数,那么我们先可以得到有cnt-n个数是可以不当做最低点的,那么我们尽量用最小的去和最小的配,为什么?
如果是1 1 2 2 的话,k=2,l=1的时候,当然是11,22是最大的,12,12是最小的,这个想想就知道了。所以有(cnt-n)/(k-1)个数是可以当做被匹配的木板。然后不一定cnt-n个数都能匹配的上,最后可能有剩余,那么就是n-(cnt-n)/(k-1)-1个数了。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100005];
int main()
{
    int n,k,l,m;
    scanf("%d%d%d",&n,&k,&l);
    m=n*k;
    for(int i=1;i<=m;i++)
        scanf("%lld",&a[i]);
    sort(a+1,a+1+m);
    if(a[n]-a[1]>l)
        printf("0\n");
    else if(k==1)
    {
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans+=a[i];
        printf("%lld\n",ans);
    }
    else
    {
        int cnt=1;
        while(a[cnt]-a[1]<=l&&cnt<=m)
            cnt++;
        cnt--;
        int pos=(cnt-n)/(k-1);
        ll ans=0;
        for(int i=1,j=1;i<=pos;i++,j+=k)
            ans+=a[j];
        ans+=a[pos*k+1];
        for(int i=1;i<n-pos;i++)
            ans+=a[cnt--];
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/82694507