Forsaken给学生分组

链接:https://ac.nowcoder.com/acm/contest/1221/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

        Forsaken有nnn个学生,每个学生都有一个能力值aia_iai,为了方便管理,Forsaken决定将nnn个学生分成kkk组。
        Forsaken认为如果一个小组有一个能力在该小组极其突出的学生,这个小组就比较容易管理。我们定义对于teamiteam_iteami来说,这个小组的管理方便度f(i)=max(aj∈teami)−min(aj∈teami)f(i) = max(a_j \in team_i) - min(a_j \in team_i)f(i)=max(ajteami)min(ajteami)。Forsaken现在想知道max(∑i=1kf(i))max(\sum_{i=1}^{k}f(i))max(i=1kf(i))。

输入描述:

第一行两个整数分别为n,kn,kn,k。
第二行nnn个数分别代表a1,a2...ana_1,a_2...a_na1,a2...an

输出描述:

一个整数表示最大的管理方便度之和。
示例1

输入

复制
5 1
10 6 2 7 9

输出

复制
8

备注:

1≤n≤1e51 \leq n \leq 1e51n1e5
1≤k≤n1 \leq k \leq n1kn
1≤ai≤1e91 \leq a_i \leq 1e91ai1e9
 
思路:贪心
对于每个组,要有一个最大值-最小值,不用管这个组里的其他数字。
当 (组数*2)k*2>n(数字的个数)时,就会出现一个数字一组的情况,2*k-n就是一个数为一组的组数。如果拿k-(2*k-n),那么剩下的k则表示一组里至少有一个最大值和一个最小值的情况。之后只需要统计k个最大值-最小值的和就是答案。
 
#include <iostream>
#include<bitset>
#include<algorithm>
#include<string>
#include<cmath>
using namespace std;
const int maxn= 200005;
const int maxnum =100000;
long long f[maxn];
long long dp[maxn];
int main()
{
    int n,k;
    long long ans=0;
    cin >> n >> k;
    for(int i=1;i<=n;i++)
        cin >> f[i];
    sort(f+1,f+1+n);
    int num=n;
    if(2*k>n)
    {
        k-=(2*k-n);
    }
    while(k)
    {
        ans+=(f[num]-f[n+1-num]);
        k--;
        num--;
    }
    cout << ans << endl;
    return 0;
}

 

posted @ 2019-10-26 11:07  晴天要下雨  阅读(355)  评论(0编辑  收藏  举报