B. Yet Another Array Partitioning Task

题目链接:http://codeforces.com/contest/1114/problem/B

题面:

B. Yet Another Array Partitioning Task

 B. Yet Another Array Partitioning Task

题目描述:给你一个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;
}