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

收起

 

输入

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

输出

输出这个最大和

输入样例

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

输出样例

26

相比v2,改成首尾相接的,如果首尾同号就归并。
代码:
#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];
r[ll] = rr;
l[rr] = ll;
}
int main() {
while(~scanf("%d%d",&n,&m)) {
sc = last = ;
ll sum = ,ans = ,c = ;
set<pair<ll,int> > ss;
for(int i = ;i < n;i ++) {
scanf("%lld",&d);
if(d * last < ) {
s[++ sc] = sum;
sum = d;
}
else sum += d;
last = d;
}
if(sum) s[++ sc] = sum;
if(s[] > && s[sc] > || s[] < && s[sc] < ) {
s[] += s[sc --];
}
for(int i = ;i <= sc;i ++) {
ss.insert(make_pair(abs(s[i]),i));
c += s[i] > ;
ans += (s[i] > ? s[i] : );
l[i] = i - ;
r[i] = i + ;
}
r[sc] = ;
l[] = sc;
while(c > m) {
int cur = ss.begin() -> second;
ss.erase(ss.begin());
ans -= abs(s[cur]);
s[cur] += s[l[cur]] + s[r[cur]];
ss.erase(make_pair(abs(s[l[cur]]),l[cur]));
modify(l[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 1115 最大M子段和 V3的更多相关文章

  1. 51nod 1065 最小正子段和

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

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

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

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

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

  4. 51nod 1052 最大M子段和

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1052 题意: 思路:设$dp[i][j]$表示前j个数构成i个字段时的最 ...

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

    1049 最大子段和  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 N个整数组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+ ...

  6. 51nod 循环数组最大子段和(动态规划)

    循环数组最大子段和 输入 第1行:整数序列的长度N(2 <= N <= 50000) 第2 - N+1行:N个整数 (-10^9 <= S[i] <= 10^9) 输出   输 ...

  7. 51nod 1053 最大M子段和 V2

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

  8. 51Nod 最大公约数之和V1,V2,V3;最小公倍数之和V1,V2,V3

    1040 最大公约数之和 给出一个n,求1-n这n个数,同n的最大公约数的和.比如:n = 6 1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15 输入 1个数N ...

  9. 51nod 1065 最小正子段和 (贪心)

    题目:传送门. 题意:中文题. 题解:求前缀和,并且标记每个数的下标,按照前缀和大小进行从小到大排序.随后进行遍历,如果满足下标data[i-1].id<data[i].id&& ...

随机推荐

  1. Xshell连接SqlPlus无法使用退格、删除键

    问题:在使用xshell连接CentOS7,进入SQLPLUS进行命令操作时,如果输错了信息,无法进行退格键删除(显示“^H”),同样按删除键,显示“^[[3~”. 解决:网上查找了相关资料,可以通过 ...

  2. 解决chrome浏览器插件开发者模式每次启动要确认弹出框的问题

    在日常工作中,我们经常会用到一些浏览器插件,有些插件因为没上架到浏览器的应用商店,只能以开发者模式运行,但是chrome浏览器出了限制,每次重新启动浏览器的时候,就会弹出该插件是否要禁止运行的对话框, ...

  3. 单选 textarea 赋初值

    自闭合标签赋初值用$().val(),比如:<input type="text" name="text" value="123"> ...

  4. Linux下的应用进程监控

    两个思路: 一.定时执行监控脚本 采用centos自带的crontab根据需要定时执行status.sh脚本 #!/bin/bash status=$(ps -aux | grep "rsy ...

  5. CDN 访问控制的那些事

    网络已经成为生活中必不可少的一部分,无论是清早手机翻看的新闻八卦,还是公交地铁里刷的停不下来的短视频,又或是你闲逛的购物网站,热追的电视剧,都与 CDN 有着密不可分的联系.无论你在互联网上做什么,或 ...

  6. 【题解】Luogu P5294 [HNOI2019]序列

    原题传送门 题意:给你一个长度为\(n\)的序列\(A\),每次询问修改一个元素(只对当前询问有效),然后让你找到一个不下降序列\(B\),使得这两个序列相应位置之差的平方和最小,并输出这个最小平方和 ...

  7. kibana内存设置

    kibana是一个基于NodeJS的单页web应用.而NodeJS则是基于Chrome V8引擎的.V8引擎对于内存的使用是有限制的,默认情况下,64位系统下约为1.4GB,32位系统下约为0.7GB ...

  8. Spring-Cloud之Eureka注册与发现-2

    一.Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的.SpringCloud将它集成在其 ...

  9. C# 获取系统字体方法

    //需要引用命名空间 using System.Drawing; using System.Drawing.Text; //获取系统字体方法 public dynamic GetFontNames() ...

  10. 2019 新浪 java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.新浪等公司offer,岗位是Java后端开发,因为发展原因最终选择去了新浪,入职一年时间了,也成为了面试官,之 ...