B. Yet Another Array Partitioning Task
题目链接:http://codeforces.com/contest/1114/problem/B
题面:
题目描述:给你一个n个数字的数组,要求把他划分为k块,每块的数字个数不少于m个,要求所有划分前m大的数字之和最大,输出和和划分的办法。
题目解法:很容易知道sort之后的数组取前m*k个数,之后划分再用set搞一下就可以了,需要注意最小的那个数有可能重复之后无法得到正确的结果,所以要记录一下最小的那个数的个数。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+7;
int a[maxn],b[maxn];
bool cmp(int aa,int bb){
return aa > bb;
}
int main(){
int n,k,m;
scanf("%d%d%d",&n,&m,&k);
ll sum = 0;
for(int i = 0;i < n; i++){
scanf("%d",&a[i]);
b[i] = a[i];
}
sort(b,b+n,cmp);
set<int> s;
for(int i = 0;i < m*k; i++){
sum += b[i];
s.insert(b[i]);
}
int tot = 0;
for(int i = 0;i < m*k; i++){
if(b[i] == b[m*k-1]) tot++;
}
printf("%lld\n",sum);
int j = 0;
ll ans = 0;
for(int i = 0;i < k-1; i++){
int num = 0;
for(;j < n; j++){
if(s.find(a[j]) != s.end()) {
if(a[j] == b[m*k-1])tot--;
if(tot == 0)s.erase(b[m*k-1]);
num++;
}
if(num == m){
printf("%d ",j+1);
j++;
break;
}
}
}
return 0;
}