B. Yet Another Array Partitioning Task (构造 思维 好题)

B. Yet Another Array Partitioning Task

An array 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

inputCopy
9 2 3
5 2 5 2 4 1 1 3 2
outputCopy
21
3 5
inputCopy
6 1 4
4 1 3 2 2 3
outputCopy
12
1 3 5
inputCopy
2 1 2
-1000000000 1000000000
outputCopy
0
1

Hint

In the first example, one of the optimal partitions is [5,2,5], [2,4], [1,1,3,2].

The beauty of the subarray [5,2,5] is 5+5=10.
The beauty of the subarray [2,4] is 2+4=6.
The beauty of the subarray [1,1,3,2] is 3+2=5.
The sum of their beauties is 10+6+5=21.

In the second example, one optimal partition is [4], [1,3], [2,2], [3].




题意:

给出n个数, 要求拆成k个子串, 每个子串至少m个元素, 求一种拆法使得各子串 前m个最大的数的和 的和最大

题解:

首先取出最大的mk个元素, 将其排序, 应该想到用来求和的数一定是在这些数当中
有一点思维要搞清楚: 每个子串至少m个元素, 那么只要我们取>=m个数, 就一定是取上述的那些数. 假设当前子串数的数量>m时, 为了避免浪费可以只取m个就好了(只有m个数可以用来求和).
可再假设取的数 由此看来, 要求的和, 就一定是最大的前k
m个数的和了, 因为不存在浪费的情况
对应求分割点, 遍历一遍, 发现为前k*m大的数就使tag++, tag==m时就标记为分割点即可

经验小结:

对于思维题, 要大胆假设, 逆向思维, 发散思维的来考虑, 把自己心中的疑惑, 顾虑, 统统拿出来反复的拷问, 推理…很多时候疑惑是要经过推理才能求证的


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef  long long LL;
const int inf = 1<<30;
const LL maxn = 2*1e5+10;

struct node{
    int n, i;
}pre[maxn];
bool cmp(node a, node b){
    if(a.n != b.n) return a.n>b.n;
    else return a.i<b.i;
}
int n, m, k, a[maxn];
int is[maxn]; //是否是前m*k大的数
int ans[maxn], len = 0;
int main()
{
    cin >> n >> m >> k;
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        pre[i].i = i, pre[i].n = a[i];
    }
    sort(pre+1, pre+1+n, cmp);

    LL sum = 0;
    for(int i = 1; i <= m*k; i++){
        is[pre[i].i] = true;
        sum += pre[i].n;
    }

    cout << sum << endl;
    int tag = 0, cnt = 0;
    for(int i = 1; i <= n; i++){
        if(cnt == k-1) break;
        if(is[i]){
            ++tag;
            if(tag==m){
                cout << i << " ";
                tag = 0, ++cnt;
            }
        }
    }

	return 0;
}


你可能感兴趣的:(思维,贪心)