[51nod1254]最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的。当所给的整数均为负数时和为0。
例如:{-2,11,-4,13,-5,-2, 4}将 -4 和 4 交换,{-2,11,4,13,-5,-2, -4},最大子段和为11 + 4 + 13 = 28。
Input
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
Output
输出交换一次后的最大子段和。
先考虑与左边的数字交换的情况。
枚举交换位置x,把交换后的段拆成x左边和x右边两部分算。
需要事先计算出前缀和、后缀和、后缀和的后缀最小值、(前缀和 - 前缀最大值)的前缀最小值。
和右边的数交换同理。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
#define ui unsigned int
#define ull unsigned long long
using namespace std;
const int maxn=,modd=;
ll mn1[maxn],mn2[maxn],_mn1[maxn],_mn2[maxn],pr[maxn],af[maxn],ans;
int prmx[maxn],afmx[maxn],a[maxn];
int i,j,k,n,m; int ra,fh;char rx;
inline int read(){
rx=getchar(),ra=,fh=;
while((rx<''||rx>'')&&rx!='-')rx=getchar();
if(rx=='-')fh=-,rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra*fh;
} int main(){
n=read();prmx[]=afmx[n+]=-1e9;
for(i=;i<=n;i++)a[i]=read(),pr[i]=pr[i-]+a[i],prmx[i]=max(prmx[i-],a[i]);
for(i=n;i;i--)af[i]=af[i+]+a[i],afmx[i]=max(afmx[i+],a[i]); // mn1[1]=0,mn2[1]=pr[1];
for(i=;i<=n;i++)
mn1[i]=min(mn1[i-],pr[i]-prmx[i]),
mn2[i]=min(mn2[i-],pr[i]);
// _mn1[n]=0,_mn2[n]=af[n];
for(i=n;i;i--)
_mn1[i]=min(_mn1[i+],af[i]-afmx[i]),
_mn2[i]=min(_mn2[i+],af[i]);
for(i=;i<=n;i++)
//i=15,//printf(" %lld-%lld %lld-%lld\n",af[i+1],_mn2[i+1],pr[i-1],mn1[i-1]),
ans=max(ans,(af[i+]-_mn2[i+])+(pr[i-]-mn1[i-])),
ans=max(ans,(pr[i-]-mn2[i-])+(af[i+]-_mn1[i+])),
ans=max(ans,pr[i]-mn2[i]);
printf("%lld\n",ans);
}
[51nod1254]最大子段和 V2的更多相关文章
- 51nod1254 最大子段和 V2 DP
---题面--- 题解: 表示今天做题一点都不顺.... 这题也是看了题解思路然后自己想转移的. 看的题解其实不是这道题,但是是这道题的加强版,因为那道题允许交换k对数. 因为我们选出的是连续的一段, ...
- 51nod 1053 最大M子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所有正数的和. 例如:-2 ...
- 最大M子段和 V2
51nod1053 这题还是我们熟悉的M子段和,只不过N,M<=50000. 这题似乎是一个堆+链表的题目啊 开始考虑把所有正数负数锁在一起. 比如: 1 2 3 -1 –2 -3 666 缩成 ...
- 51nod 1254 最大子段和 V2 ——单调栈
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod 1254 最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- 51nod1524 最大子段和V2
题干 N个整数组成的序列a[1],a[2],a[3],-,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数 ...
- 51Nod1053 最大M子段和V2 二分+DP
传送门 直接DP的话最多也只能做到\(O(nm)\),对于\(5\times 10^4\)的数据范围实在无能为力 夹克老爷提供的做法是贪心,思想大概是在调整的同时,合理构造每个选择对应的新状态,使得新 ...
- 51nod1053 最大M子段和 V2
$n \leq 50000$的序列,问选不超过$m \leq 50000$个区间使得和最大. 如果正数区间总数比$m$小那肯定全选.否则有两种方式减少区间数量:丢掉一个正区间:补一个负区间连接两个正区 ...
- 51Nod 最大M子段和系列 V1 V2 V3
前言 \(HE\)沾\(BJ\)的光成功滚回家里了...这堆最大子段和的题抠了半天,然而各位\(dalao\)们都已经去做概率了...先%为敬. 引流之主:老姚的博客 最大M子段和 V1 思路 最简单 ...
随机推荐
- Swift基础学习
Swift基础学习 http://c.biancheng.net/cpp/html/2242.html 这个网站最近看了一下,对于基本语法解释概括的相对全面,如同重新练习一遍OC似的,挺全面的,谢谢 ...
- Windows下RabbitMQ安装及入门
1.Windows下安装RabbitMQ需要以下几个步骤 (1):下载erlang,原因在于RabbitMQ服务端代码是使用并发式语言erlang编写的,下载地址:http://www.erlang. ...
- 解决 mysql 中文乱码
mysql版本:5.6.38 虽然创建实例时选择的是utf-8的utf8_general_ci,但是用其他程序保存中文时依旧出现乱码的情况. 记录一种可行的解决方案,即修改数据库的字符集. 由于该环境 ...
- windows下查看端口占用情况及关闭相应的进程
经常,我们在启动应用的时候发现系统需要的端口被别的程序占用,如何知道谁占有了我们需要的端口,很多人都比较头疼,下面就介绍一种非常简单的方法. 例如:需要查看9001端口被谁占用,并将其进程强制关闭 在 ...
- Windows下使用OpenSSL生成自签证书
下载OpenSSLhttp://slproweb.com/products/Win32OpenSSL.html 生成证书 生成crt证书CMD进入安装bin目录,执行命令:openssl req -x ...
- javamelody 使用
javamelody 扩展API如何获取监控参数 https://github.com/javamelody/javamelody/wiki/ExternalAPI#json
- Git详解之八:Git与其他系统
Git 与其他系统 世界不是完美的.大多数时候,将所有接触到的项目全部转向 Git 是不可能的.有时我们不得不为某个项目使用其他的版本控制系统(VCS, Version Control System ...
- MySQL查询相关(初级)(全文重点)
where 是约束条件 先找到表 from t1 where 条件 : 指的是把表里的数据,一条一条的记录取出来 然后 group by 分组, having 是过滤条件 指记录已经出来 聚合 cou ...
- Head First设计模式之装饰者模式
一.定义 装饰者模式,英文叫Decorator Pattern,在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 动态将职责附加到 ...
- CHECKDB内部:什么是BlobEater?
DBCC CHECKDB注意到有关数据文件页面.一旦整个表的所有页(或一组表,如果配料已启用-看到同样的博客文章我上面提到的),所有的事实都聚集在一起,他们都应该相互抵消.当有额外的事实(在索引B树都 ...