链接:https://ac.nowcoder.com/acm/contest/1221/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
空间限制: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(aj∈teami)−min(aj∈teami)。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≤n≤1e51 leq n leq 1e51≤n≤1e5
1≤k≤n1 leq k leq n1≤k≤n
1≤ai≤1e91 leq a_i leq 1e91≤ai≤1e9
思路:贪心
对于每个组,要有一个最大值-最小值,不用管这个组里的其他数字。
当 (组数*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; }