CF#538(div2) B. Yet Another Array Partitioning Task 【YY】
任意门:http://codeforces.com/contest/1114/problem/B
B. Yet Another Array Partitioning Task
2 seconds
256 megabytes
standard input
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.
The first line contains three integers nn, mm and kk (2≤n≤2⋅1052≤n≤2⋅105, 1≤m1≤m, 2≤k2≤k, m⋅k≤nm⋅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 (−109≤ai≤109−109≤ai≤109).
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−1k−1 integers p1,p2,…,pk−1p1,p2,…,pk−1 (1≤p1<p2<…<pk−1<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 pk−1+1pk−1+1 to nn belong to the last, kk-th subarray.
If there are several optimal partitions, print any of them.
9 2 3
5 2 5 2 4 1 1 3 2
21
3 5
6 1 4
4 1 3 2 2 3
12
1 3 5
2 1 2
-1000000000 1000000000
0
1
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:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = 2e5+;
int num[MAXN];
int numa[MAXN];
int cnt, anum;
int ans[MAXN], nn;
int N, M, K;
map<int, bool>mmp;
bool cmp(int a, int b)
{
return a > b;
} int main()
{
scanf("%d %d %d", &N, &M, &K);
for(int i = ; i <= N; i++){
scanf("%d", &num[i]);
numa[cnt++] = num[i];
//num[i].no = i;
}
LL ans_sum = 0LL;
sort(numa, numa+cnt, cmp);
for(int i = ; i < M*K; i++){
ans_sum += numa[i];
//mmp[numa[i]] = true;
//printf("%d\n", numa[i]);
}
LL lst = numa[M*K-];
//printf("lst:%d\n", lst);
int j = M*K-;
while(numa[j] == lst && j >= ){
anum++;
j--;
} int tt = ;
for(int i = ; i <= N; i++){
if(num[i] > lst){
tt++;
if(tt == M){
ans[nn++] = i;
tt = ;
}
}
else if(num[i] == lst && anum){
anum--;
tt++;
if(tt == M){
ans[nn++] = i;
tt = ;
}
}
} printf("%I64d\n", ans_sum);
for(int i = ; i < nn-; i++){
printf("%d ", ans[i]);
}
puts("");
return ;
}
CF#538(div2) B. Yet Another Array Partitioning Task 【YY】的更多相关文章
- Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏【转】
Java虚拟机性能管理神器 - VisualVM(7) 排查JAVA应用程序线程泄漏[转] 标签: javajvm线程泄漏 2015-03-11 19:47 1098人阅读 评论(0) 收藏 举报 ...
- Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏【转】
Java虚拟机性能管理神器 - VisualVM(6) 排查JAVA应用程序内存泄漏[转] 标签: javajvm内存泄漏监控工具 2015-03-11 18:30 1870人阅读 评论(0) 收藏 ...
- Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁【转】
Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁[转] 标签: javajvm监控工具性能优化 2015-03-11 19:59 1948人阅读 评论(0) 收藏 ...
- 机器人操作系统(ROS)教程4:ROS的框架【转】
转自:http://www.arduino.cn/thread-11351-1-1.html 在进行ROS的代码开发前,有必要了解一些ROS的概念.首先,ROS的系统代码分为两部分:main和univ ...
- linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-119723.html linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟 xxxxxxxxxx ...
- inux设备驱动归纳总结(五):2.操作硬件——IO内存【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-80627.html inux设备驱动归纳总结(五):2.操作硬件——IO内存 xxxxxxxxxxxx ...
- linux设备驱动归纳总结(五):1.在内核空间分配内存【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-79134.html linux设备驱动归纳总结(五):1.在内核空间分配内存 xxxxxxxxxxxx ...
- linux设备驱动归纳总结(四):1.进程管理的相关概念【转】
本文转载自;http://blog.chinaunix.net/uid-25014876-id-64866.html linux设备驱动归纳总结(四):1.进程管理的相关概念 xxxxxxxxxxxx ...
- linux设备驱动归纳总结(三):5.阻塞型IO实现【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-60025.html linux设备驱动归纳总结(三):5.阻塞型IO实现 xxxxxxxxxxxxxx ...
随机推荐
- NoSQL集锦
1. http://blog.nosqlfan.com/,有不少Redis.CouchDB.MongoDB的电子书和文章,但没有Memcached的.
- Java - 让1+1的结果变成3
原出处是国外某论坛某帖子中楼主提问:如何让1+1=3?于是出现了各种语言实现的各种机制的答案,当然其中也包括直接用字符串输出"1+1=3"...最后被采纳的是用Java语言实现的答 ...
- git flow强制重新初始化
Gitflow工作流定义了一个围绕项目发布的严格分支模型. git flow初始化命令: git flow init 关于各个分支的命名一路回车就可以了,如果不小心修改了默认的分支命名,后来又觉得不爽 ...
- 07.重写ToSting()方法
namespace _08.重写ToString方法 { class Program { static void Main(string[] args) { Person p = new Person ...
- URL 编码 之 我见
URL编码 编辑 url编码是一种浏览器用来打包表单输入的格式.浏览器从表单中获取所有的name和其中的值 ,将它们以name/value参数编码(移去那些不能传送的字符,将数据排行等等)作为URL的 ...
- [SYZOI Round1] 滑稽♂树
题面 传送门 Sol 我也不知道哪里来的题目哪里来的\(OJ\) 子树变成\(DFS\)序后就是裸的树套树 # include <bits/stdc++.h> # define RG re ...
- Sort函数的用法
快速排序sort的用法:(适用于int float double char ...) 记得加头文件! 记得加头文件! 记得加头文件! 头文件: #include <algorithm> ...
- RocketMQ读书笔记2——生产者
[生产者的不同写入策略] 生产者向消息队列里写入数据,不同的业务需要生产者采用不同的写入策略: 同步发送.异步发送.延迟发送.发送事务消息等. [DefaultMQProduce示例] public ...
- Java数字和字符串的相互转换(BigDecimal的使用)
String s = "100."; double d1 = "1.23"; double d = Double.parseDouble(s); s = Str ...
- C语言输入语句scanf与fgets linux下
1.测试使用scanf的一个例子: #include "stdio.h" #include "string.h" int main() { char name[ ...