N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的。如果M >= N个数中正数的个数,那么输出所有正数的和。
例如:-2 11 -4 13 -5 6 -2,分为2段,11 -4 13一段,6一段,和为26。

收起

 

输入

第1行:2个数N和M,中间用空格分隔。N为整数的个数,M为划分为多少段。(2 <= N , M <= 50000)
第2 - N+1行:N个整数(-10^9 <= a[i] <= 10^9)

输出

输出这个最大和

输入样例

7 2
-2
11
-4
13
-5
6
-2

输出样例

26

v2果然是难了,还用dp就超时了,学无止境,本道题采用特别巧妙的贪心思想的方法,把相邻的正数或者负数,都加到一起,形成新的序列,也就是正数和负数交叉的序列,假如原序列是1 2 -3 -4 3,压缩后:
3 -7 3,存到一个新的数组里,我们用ans记录所有正数的和,显然新数组里每一项都是一段,我们还要记录所有正数段得到个数,我们要保持正数段的个数在m之内,所以我们把所有的数段的绝对值,以及位置,存到一个set里,
也可以用链表,这样做的目的是用负数填补空缺,从而把两个正数段合并为一段,我们需要知道每一段左右分别是谁,方便合并,不是单纯的下表加1和减1,因为合并多了,中间会有很多无效的位置,当然了用链表就不需要考虑这些问题,直接删除节点即可。
那么怎么来合并呢,set里存绝对值和位置组成的pair,这样排序就按照绝对值排序了,每次选择绝对值最小的,假如这个数是正的,那么就用ans减去,然后跟两边的合并,因为set里所有的负数绝对值都比他大,所以ans肯定不包括它了,如果是负数,也是ans减去绝对值,负数跟两边的整数合并了,实际上让ans减少了。
代码:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <set>
using namespace std;
typedef long long ll;
int n,m;
ll d,last;
ll s[];
int l[],r[];
int sc;
void modify(int cur) {///修改左右相邻结点的下标
int ll = l[cur],rr = r[cur];
if(ll) {
r[ll] = rr;
}
if(rr) {
l[rr] = ll;
}
}
int main() {
while(~scanf("%d%d",&n,&m)) {
ll sum = ,ans = ,c = ;
set<pair<ll,int> > ss;
for(int i = ;i < n;i ++) {
scanf("%lld",&d);
if(d * last < ) {
s[++ sc] = sum;
if(sc == && sum < ) sc --;
sum = d;
}
else sum += d;
last = d;
}
if(sum > ) s[++ sc] = sum;
c = (sc + ) / ;
for(int i = ;i <= sc;i ++) {
ss.insert(make_pair(abs(s[i]),i));
ans += (s[i] > ? s[i] : );
l[i] = i - ;
r[i] = i + ;
}
r[sc] = ;
while(c > m) {
int cur = ss.begin() -> second;
ss.erase(ss.begin());
if(s[cur] < && (!l[cur] || !r[cur])) continue;///如果是负数,而且是处在首尾的位置那么就没必要合并了。
ans -= abs(s[cur]);
s[cur] += s[l[cur]] + s[r[cur]];
if(l[cur]) {
ss.erase(make_pair(abs(s[l[cur]]),l[cur]));
modify(l[cur]);
}
if(r[cur]) {
ss.erase(make_pair(abs(s[r[cur]]),r[cur]));
modify(r[cur]);
}
if(s[cur]) ss.insert(make_pair(abs(s[cur]),cur));
c --;
}
printf("%lld\n",ans);
}
return ;
}

51nod 1053 最大M子段和 V2的更多相关文章

  1. 51nod 1065 最小正子段和

    题目链接:51nod 1065 最小正子段和 房教说用前缀和做,然后看了别人博客懂了后就感觉,这个真有意思... #include<cstdio> #include<cstring& ...

  2. 51nod 1254 最大子段和 V2 ——单调栈

    N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

  3. 51nod 1254 最大子段和 V2

    N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

  4. 51nod 循环数组最大子段和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 对于普通的数组,只要求一次最大子段和即可.但是这题是可以循环的,所 ...

  5. 51nod 1049 1049 最大子段和 (dp)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049 令 dp[i]表示为以a[i]结尾的最大子段和,则  dp[i]= ...

  6. 51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1084 1084 矩阵取数问题 V2  基准时间限制:2 秒 空 ...

  7. 51nod 1115 最大M子段和 V3

    环形最大M子段和,N个整数组成的序列排成一个环,a[1],a[2],a[3],…,a[n](a[n-1], a[n], a[1]也可以算作1段),将这N个数划分为互不相交的M个子段,并且这M个子段的和 ...

  8. 最大M子段和 V2

    51nod1053 这题还是我们熟悉的M子段和,只不过N,M<=50000. 这题似乎是一个堆+链表的题目啊 开始考虑把所有正数负数锁在一起. 比如: 1 2 3 -1 –2 -3 666 缩成 ...

  9. [51nod1254]最大子段和 V2

    N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...

随机推荐

  1. Lock Free (无锁并发)

    CAS( compare and swap) 原子操作,保证了如果需要更新的地址没有被其他进程(线程)改动过,那么它可以安全的写入.而这也是我们对于某个数据或者数据结构加锁要保护的内容,保证读写的一致 ...

  2. java中通过Adb判断PC是否连接了移动设备

    最近用到PC端和移动端通过USB连接传输数据的方式,于是总在使用Adb命令,为了逻辑的严谨和代码容错,想在传输数据的之前,PC和移动端先建立一次会话,防止移动端还未连接就直接传输数据会报错,找了很久并 ...

  3. python ---socket初识

    python网络编程(初识) 一些概念 套接字: 套接字(socket)也叫通信端点,最初用于计算机内部进程之间的通信,而随着网络的发展,套接字被用于计算机之间的通信.举个例子,你(是一台计算机)要打 ...

  4. 基于FPGA Manager的Zynq PL程序写入方案

    本文主要描述了如何在Linux系统启动以后,在线将bitstream文件更新到ZYNQ PL的过程及方法.相关内容主要译自xilinx-wiki,其中官网给出了两种方法,分别为Device Tree ...

  5. 嵌入式web服务器BOA+CGI+HTML+MySQL项目实战——Linux

    准备环境操作系统: Ubuntu12.04 LTS环境搭建: 需要 BOA,Apache,CCGI,MySQL,GCC[Linux下嵌入式Web服务器BOA和CGI编程开发][数据库的相关知识——学习 ...

  6. JavaWeb项目之多条件过滤

    相信很多同学在学习java基础之后,面对各种项目还是相当头疼,那今天我将手把手教你学会JavaWeb项目中的多条件过滤,希望你能在与我实战的过程中积累经验,更进一步. 分页查询 需求分析:在列表页面中 ...

  7. Vue的router-link标签

    在vue1.0版本的超链接标签还是原来的a标签,链接地址由v-link属性控制 而vue2.0版本里超链接标签由a标签被替换成了router-link标签,但最终在页面还是会被渲染成a标签的 至于为什 ...

  8. Jenkins+harbor+gitlab+k8s 部署maven项目

    一.概述 maven项目部署流程图如下: 环境介绍 操作系统 ip 角色 版本 ubuntu-16.04.4-server-amd64 192.168.10.122 Jenkins+harbor Je ...

  9. js提取135编辑器相同的css

    135编辑器导入的内容,有重复的很多css,导致加载很慢,只能去掉 function remove135FormatContent(content){ if(!content) return ''; ...

  10. NET Core 3.0 AutoFac替换内置DI的新姿势

    原文:NET Core 3.0 AutoFac替换内置DI的新姿势 .NET Core 3.0 和 以往版本不同,替换AutoFac服务的方式有了一定的变化,在尝试着升级项目的时候出现了一些问题. 原 ...