Time Limit: 1 second

Memory Limit: 128 MB

【问题描述】

给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大。

【输入格式】

输入文件maxsum2.in的第一行是一个正整数N,表示了序列的长度。 第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列,第一个数和第N个数是相邻的。

【输出格式】

输入文件maxsum2.out仅包括1个整数,为最大的两段子段和是多少。

【数据规模】

对于40%的数据,有2 ≤ N ≤ 2000。 对于100%的数据,有N ≤ 200000。

Sample Input1

7

2 -4 3 -1 2 -4 3

Sample Output1

9

【样例解释】

一段为3 –1 2,一段为3 2

*2 -4 *3 *-1 *2 -4 *3

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u124

【题解】



假设最后的答案区间被涂上红色;则最后答案一定是以下两种形式;(把环看成是直线);





对于第一种情况,只要枚举两个区间的断点就可以了;

枚举前要用最大子段和问题的普通形式的数组弄个前缀和和后缀和;

枚举的时候左边和右边直接加起来就是两个红色部分的了;

而对于第二种情况

我们可以转换成求中间两段黑色的部分;让它的和最小;即求两段子段和最小;然后用总数减去它就是最大的了;

两种情况取最大值就好;

用第二种方法求解是有条件的;

即数组中的正数的个数要大于1个;

比如

没有正数

5

-1 -1 -1 -1 -1

如果用了第二种答案为0(程序认为黑色部分两段和的最小值为-5而总和为-5…);正确答案是-2,第一种才能求出来;

只有一个正数也不行

5

-1 -1 -1 -1 5

第二种答案为5(两个最小部分和为-4,总和为1);但是如果答案为5的话就没有选出两段出来,因此正确答案为第一种求出来的4才对;



【完整代码】

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second typedef pair<int,int> pii;
typedef pair<LL,LL> pll; void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
} void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
} const int MAXN = 2e5+100;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0); int n;
int pltor[MAXN],ltor[MAXN],prtol[MAXN],rtol[MAXN],a[MAXN];
int pltor1[MAXN],ltor1[MAXN],prtol1[MAXN],rtol1[MAXN]; int main()
{
//freopen("D:\\rush.txt","r",stdin);
int total=0,cnt=0;
rei(n);
rep1(i,1,n)
{
rei(a[i]);
if (a[i]>0)
cnt++;
total+=a[i];
}
pltor[0]=-21e8;
pltor1[0]=21e8;
rep1(i,1,n)
{
ltor[i] = max(a[i],ltor[i-1]+a[i]);
pltor[i] = max(pltor[i-1],ltor[i]);
ltor1[i] = min(a[i],ltor1[i-1]+a[i]);
pltor1[i] = min(pltor1[i-1],ltor1[i]);
}
prtol[n+1]=-21e8;
prtol1[n+1]=21e8;
rep2(i,n,1)
{
rtol[i] = max(a[i],rtol[i+1]+a[i]);
prtol[i] = max(prtol[i+1],rtol[i]);
rtol1[i] = min(a[i],rtol1[i+1]+a[i]);
prtol1[i] = min(prtol1[i+1],rtol1[i]);
}
int ans1 = -21e8,ans2=21e8;
rep1(i,1,n-1)
{
int temp = pltor[i]+prtol[i+1];
ans1 = max(ans1,temp);
temp = pltor1[i]+prtol1[i+1];
ans2 = min(ans2,temp);
}
if (cnt>1 && total-ans2>ans1)
ans1 = total-ans2;
printf("%d\n",ans1);
return 0;
}

【u124】环状最大两段子段和的更多相关文章

  1. 洛谷 P1121 环状最大两段子段和 解题报告

    P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为\(A_1\)和\(A_N\)是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 第一行是一个正整数 ...

  2. P1121 环状最大两段子段和

    P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的 ...

  3. P1121 环状最大两段子段和(DP)

    P1121 环状最大两段子段和 难度 提高+/省选- 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件 ...

  4. 洛谷P1121 环状最大两段子段和

    题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的第一行是一个正整数N,表示了序列 ...

  5. 洛谷 P1121 环状最大两段子段和

    https://www.luogu.org/problemnew/show/P1121 不会做啊... 看题解讲的: 答案的两段可能有两种情况:一是同时包含第1和第n个,2是不同时包含第1和第n个 对 ...

  6. luogu 1121 环状最大两段子段和

    题目大意: 一个序列看做一个环 选两段数使它们和最大 思路: 定义一个dp数组i j 0/1 表示前i个取了连续的j段 0/1表示取不取第i个 但是因为看做一个环 首尾相接的情况可以看做是选三段,其中 ...

  7. Luogu1121:环状最大两段子段和

    题面 传送门 Sol 两种情况 第一种就是类似\(***000***000***(0表示选)\),这个可以DP 设\(h[0/1/2/3][i]\)表示到第\(i\)位的状态: \(0\):表示还没选 ...

  8. luogu P1121 环状最大两段子段和

    嘟嘟嘟 一道说难也难说简单也简单的dp题. 我觉得我的(有篇题解)做法就属于特别简单的. 平时遇到环的问题都是断环为链,但这道题给了一种新的思路. 观察一下,最后的答案无非就这两种:xxx--xx-- ...

  9. 洛谷 P1121 环状最大两段子段和 题解

    每日一题 day57 打卡 Analysis 对于这个问题,由于分成了两个子序列,我们不妨就是枚举一下可能出现的情况: 无非就这两种: 1.+++++0000+++++0000++++ 2.0000+ ...

随机推荐

  1. [Javascript] Classify JSON text data with machine learning in Natural

    In this lesson, we will learn how to train a Naive Bayes classifier and a Logistic Regression classi ...

  2. iOS 基于第三方QQ授权登录

    基于iOS实现APP的第三方QQ登陆.接入第三方SDK时的一个主要的步骤: 1,找到相关的开放平台.QQ互联平台,http://connect.qq.com/: 2,注冊成功后创建自己的APP.填写一 ...

  3. 妙味css3课程---1-2、css3中新增的伪类和伪元素有哪些

    妙味css3课程---1-2.css3中新增的伪类和伪元素有哪些 一.总结 一句话总结: 1.div:target{}是什么意思? 比如a标签的锚点链接到div,div:target{}就可以找到这个 ...

  4. 比较s+=4;和s=s+4;的不同

    1.s=s+4: public class Test { public static void main(String[] args){ short s=3; // s=s+4; //描述 资源 路径 ...

  5. ::的类名前有个 & ,什么意思?

    转载自  http://www.imooc.com/qadetail/93985 MazePerson &MazePerson::setPersonPosition(int coordinat ...

  6. natapp解决Invalid Host header的问题

    最近在做一个微信公众号项目,用微信开发工具调试本地项目,需要做一下内网穿透,代理都配置好了,页面出现这个Invalid Host header错误,内网穿透工具我是用的frps做的,最后通过googl ...

  7. 进阶攻略|最全的前端开源JS框架和库

    新的 Javascript 库层出不穷,从而Web 社区愈发活跃.多样.在多方面快速发展.详细去描述每一种主流的 Javascript框架和库近乎不可能,所以在这篇文章中主要介绍一些对前端发展最具影响 ...

  8. 洛谷——V1772 巧妙填数

    描述 将1,2,\cdots,91,2,⋯,9共99个数分成三组,分别组成三个三位数,且使这三个三位数构成1:2:31:2:3的比例. 试求出所有满足条件的三个三位数.例如:三个三位数192,384, ...

  9. amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules

    amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules 一.总结 1.am:以 am 为命名空间 2.模块状态: {命名空间}-{模块名}-{状态描述} 3.子模块: {命名空间}- ...

  10. 【2017 Multi-University Training Contest - Team 7 && hdu 6121】Build a tree

    [链接]点击打开链接 [题意] 询问n个点的完全k叉树,所有子树节点个数的异或总和为多少. [题解] 考虑如下的一棵k=3叉树,假设这棵树恰好有n个节点. 因为满的k叉树,第i层的节点个数为k^(i- ...