zoukankan      html  css  js  c++  java
  • CF#538(div2) B. Yet Another Array Partitioning Task 【YY】

    任意门:http://codeforces.com/contest/1114/problem/B

    B. Yet Another Array Partitioning Task

    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    An array bb is called to be a subarray of aa if it forms a continuous subsequence of aa, that is, if it is equal to alal, al+1al+1, …, arar for some l,rl,r.

    Suppose mm is some known constant. For any array, having mm or more elements, let's define it's beauty as the sum of mm largest elements of that array. For example:

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

    You are given an array a1,a2,,ana1,a2,…,an, the value of the said constant mm and an integer kk. Your need to split the array aa into exactly kksubarrays such that:

    • Each element from aa belongs to exactly one subarray.
    • Each subarray has at least mm elements.
    • The sum of all beauties of kk subarrays is maximum possible.
    Input

    The first line contains three integers nn, mm and kk (2n21052≤n≤2⋅105, 1m1≤m, 2k2≤k, mknm⋅k≤n) — the number of elements in aa, the constant mm in the definition of beauty and the number of subarrays to split to.

    The second line contains nn integers a1,a2,,ana1,a2,…,an (109ai109−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 k1k−1 integers p1,p2,,pk1p1,p2,…,pk−1 (1p1<p2<<pk1<n1≤p1<p2<…<pk−1<n) representing the partition of the array, in which:

    • All elements with indices from 11 to p1p1 belong to the first subarray.
    • All elements with indices from p1+1p1+1 to p2p2 belong to the second subarray.
    • ….
    • All elements with indices from pk1+1pk−1+1 to nn belong to the last, kk-th subarray.

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

    Examples
    input
    Copy
    9 2 3
    5 2 5 2 4 1 1 3 2
    
    output
    Copy
    21
    3 5 
    input
    Copy
    6 1 4
    4 1 3 2 2 3
    
    output
    Copy
    12
    1 3 5 
    input
    Copy
    2 1 2
    -1000000000 1000000000
    
    output
    Copy
    0
    1 
    Note

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

    • The beauty of the subarray [5,2,5][5,2,5] is 5+5=105+5=10.
    • The beauty of the subarray [2,4][2,4] is 2+4=62+4=6.
    • The beauty of the subarray [1,1,3,2][1,1,3,2] is 3+2=53+2=5.

    The sum of their beauties is 10+6+5=2110+6+5=21.

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

    题意概括:

    将长度为 N 的数串分成 K 段,每段取 M 大值,要求每段 M 大值最后相加的总和最大,求分段方案,并输出断点。

     

    解题思路:

    暴力,最优的方案当然是选出 M*K 个的值都是最大啦,先降序排序 取 前 M*K 个。

    暴力扫一遍原序列,如果遇到 这些前 M*K 大的值就取,取到 M 个就分段。

    到这里好像没毛病....然而 wa。

    有一个细节遗漏了,就是第 M*K 大的值如果不止一个,而是有多个,但这些值按照排序并为在前 M*K 中,但在原序列里,这些值处在比他们大得值前面,那么我们扫描原序列时就会把这些值加进去,而有可能省略了后面更大的值,这个方案肯定不是最优的。

    所以第 M*K 个值需要特判!

    AC code:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<vector>
     6 #include<queue>
     7 #include<cmath>
     8 #include<map>
     9 #include<set>
    10 #define INF 0x3f3f3f3f
    11 #define LL long long
    12 using namespace std;
    13 const int MAXN = 2e5+10;
    14 int num[MAXN];
    15 int numa[MAXN];
    16 int cnt, anum;
    17 int ans[MAXN], nn;
    18 int N, M, K;
    19 map<int, bool>mmp;
    20 bool cmp(int a, int b)
    21 {
    22     return a > b;
    23 }
    24 
    25 int main()
    26 {
    27     scanf("%d %d %d", &N, &M, &K);
    28     for(int i = 1; i <= N; i++){
    29         scanf("%d", &num[i]);
    30         numa[cnt++] = num[i];
    31         //num[i].no = i;
    32     }
    33     LL ans_sum = 0LL;
    34     sort(numa, numa+cnt, cmp);
    35     for(int i = 0; i < M*K; i++){
    36         ans_sum += numa[i];
    37         //mmp[numa[i]] = true;
    38         //printf("%d
    ", numa[i]);
    39     }
    40     LL lst = numa[M*K-1];
    41     //printf("lst:%d
    ", lst);
    42     int j = M*K-1;
    43     while(numa[j] == lst && j >= 0){
    44         anum++;
    45         j--;
    46     }
    47 
    48     int tt = 0;
    49     for(int i = 1; i <= N; i++){
    50         if(num[i] > lst){
    51             tt++;
    52             if(tt == M){
    53                 ans[nn++] = i;
    54                 tt = 0;
    55             }
    56         }
    57         else if(num[i] == lst && anum){
    58             anum--;
    59             tt++;
    60             if(tt == M){
    61                 ans[nn++] = i;
    62                 tt = 0;
    63             }
    64         }
    65     }
    66 
    67     printf("%I64d
    ", ans_sum);
    68     for(int i = 0; i < nn-1; i++){
    69         printf("%d ", ans[i]);
    70     }
    71     puts("");
    72     return 0;
    73 }
  • 相关阅读:
    H5项目开发分享——用Canvas合成文字
    《JavaScript设计模式 张》整理
    Linux常用指令指南,终端装逼利器
    飞起来的正则表达式
    JavaScript特性(attribute)、属性(property)和样式(style)
    使用 Nginx 提升网站访问速度
    centos 邮件服务 腾讯企业邮箱(免费) 使用iRedmail 需要有公网的centos主机 发邮件协议:smtp 端口25 收邮件协议:pop3 端口110 iredmail安装配置 使用邮箱系统 第三十一节课
    用nginx的反向代理机制解决前端跨域问题在nginx上部署web静态页面
    mysql字符集调整总结
    因为smb和nfs挂掉导致客户端开机启动不了
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10361488.html
Copyright © 2011-2022 走看看