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. Highcharts图表的注解功能

    Highcharts图表的注解功能 在图表中,往往须要对图表总体或者部分元素进行对应注解.帮助浏览者阅读图表.尽管标签组labels能够实现类似的功能.可是其功能相对简单.要实现复杂的注解功能,用户能 ...

  2. 编写一个程序,把指定目录下的所有的带.java文件都拷贝到另一个目录中,拷贝成功后,把后缀名是.java的改成.txt。

    package example; import java.io.*; public class Test { public static void main(String[] args) throws ...

  3. Spider_lxml

    xpath工具(解析) xpath 在XML文档中查找信息的语言,同样适用于HTML文档的检索 xpath辅助工具 Chrome插件 :XPath Helper 打开 :Ctrl + Shift + ...

  4. 【例题 8-4 UVA - 11134】Fabled Rooks

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然把问题分解成两个子问题. x轴和y轴分别做. 即n个点要求第i个点在[li,ri]范围内.(ri<=n) 问是否可行. 按 ...

  5. 杭电1102 Constructing Roads

    Constructing Roads Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. Apache中PHP5.3 php5.4如何使用ZEND

    Apache中PHP5.3 php5.4如何使用ZEND 有一套zend加密程序,需要安装ZEND,经过多次尝试,结果如下 由于PHP有安全线程(TS)和非安全线程(NTS)区分,PHP官方网站上说, ...

  7. GestureDetector-onfling不执行

    今天在做计算器的时候,遇到了一个问题,就是当我使用GestureDetector的时候,onFling方法不执行,而其他的可以执行.代码如下 @Override public boolean onDo ...

  8. 认识一下JavaScript

    1.什么是JavaScript? JavaScript简称“JS”,应用于HTML和WEB,广泛应用于服务器.PC.笔记本等设备. JavaScript 是 Web 的编程语言. 所有现代的 HTML ...

  9. Maven搭建Spring Security3.2项目详解

    本来是打算在上一篇SpringMVC+Hibernate上写的,结果发现上面那篇 一起整合的,结果发现上一篇内容实在是太长了,就另起一篇,这篇主要是采用 Maven搭建Spring+SpringMVC ...

  10. iOS 之应用性能调优的25个建议和技巧

    注意:每在优化代码之前,你都要注意一个问题,不要养成"预优化"代码的错误习惯. 时常使用Instruments去profile你的代码来发现须要提升的方面.Matt Gallowa ...