Codeforces Round #538 (Div. 2) Yet Another Array Partitioning Task(贪心)

链接:http://codeforces.com/problemset/problem/1114/B
来源:Codeforces

Aay b is called to be a subarray of a if it forms a continuous subsequence of a, that is, if it is equal to al, al+1, …, ar for some l,r.
Suppose m is some known constant. For any array, having m or more elements, let’s define it’s beauty as the sum of m largest elements of that array. For example:

  • For array x=[4,3,1,5,2] and m=3, the 3 largest elements of x are 5, 4 and 3, so the beauty of x is 5+4+3=12.
  • For array x=[10,10,10] and m=2, the beauty of x is 10+10=20.

    You are given an array a1,a2,…,an, the value of the said constant m and an integer k. Your need to split the array a into exactly k subarrays such that:
  • Each element from a belongs to exactly one subarray.
  • Each subarray has at least m elements.
  • The sum of all beauties of k subarrays is maximum possible.

Input

The first line contains three integers n, m and k (2≤n≤2⋅105, 1≤m, 2≤k, m⋅k≤n) — the number of elements in a, the constant m in the definition of beauty and the number of subarrays to split to.

The second line contains n integers a1,a2,…,an (−109≤ai≤109).

Output

In the first line, print the maximum possible sum of the beauties of the subarrays in the optimal partition.

In the second line, print k−1 integers p1,p2,…,pk−1 (1≤p1

  • All elements with indices from 1 to p1 belong to the first subarray.
  • All elements with indices from p1+1 to p2 belong to the second subarray.
  • ….
  • All elements with indices from pk−1+1 to n belong to the last, k-th subarray.

    If there are several optimal partitions, print any of them.

Examples

  • Input
    9 2 3
    5 2 5 2 4 1 1 3 2
  • Output
    21
    3 5
  • Input
    6 1 4
    4 1 3 2 2 3
  • Output
    12
    1 3 5
  • Input
    2 1 2
    -1000000000 1000000000
  • Output
    0
    1

  此题是说将数组a(长度为n)分成k组,每一组选出m个最大的数,将这m*k个数相加能够形成的最大值,输出这个最大值,然后输出每一组的最后一个数的下标(最后一组不输出).这道题我们可以用贪心的方法,对数组排序先选出m*k个最大数的数,对他们的位置做标记.那么我们在分组的时候,每次找到两个被标记的数时我们就找到了一组,直到数组的元素全部找完为止.

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define pi 3.1415926
#define mod 1000000007
#define inf 0x3f3f3f3f
using namespace std;

//typedef pair Node;
typedef long long  LL;
const int Max_n=2*100005;
int vis[Max_n],ans[Max_n]; 

struct Node{
	int pos,val;
	bool operator <(const Node &n) const{
		return val==n.val?pos>n.pos:val>n.val;	
	}
}a[Max_n];
int main(){
	memset(vis,0,sizeof(vis));
	int n,m,k;
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i].val);
		a[i].pos=i;
	}
	LL sum=0;
	sort(a+1,a+n+1);
	for(int i=1;i<=m*k;i++){//找到m*k个数并且对他们的位置做标记
		vis[a[i].pos]=1;
		sum+=a[i].val;
	} 
	int t=0,num=1;
	for(int i=1;i<=n;i++){
		if(vis[i]){//如果此位置被标记过
			t++;
			if(t==m){//找到了一组,并标记这组的最后一个元素的位置
				t=0;
				ans[num++]=i;
			}
		}
	}
	printf("%lld\n",sum);
	for(int i=1;i<k;i++)
		printf("%d%c",ans[i],i==k?'\n':' ');
    return 0;
}

你可能感兴趣的:(Greedy)