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. HDU——T 1573 X问题

    http://acm.hdu.edu.cn/showproblem.php?pid=1573 Time Limit: 1000/1000 MS (Java/Others)    Memory Limi ...

  2. java JDK设置环境变量

    1.右键"我的电脑"图标.在弹出菜单中依次选择"属性"-"高级"-"环境变量". 2.在"环境变量" ...

  3. apache wicket 7.X之HelloWorld

    Wicket是什么 Wicket一个开发Java Web应用程序框架. 它使得开发web应用程序变得easy而轻松. Wicket利用一个POJO data beans组件使得它能够与不论什么持久层技 ...

  4. BZOJ3620: 似乎在梦中见过的样子(KMP)

    Description “Madoka,不要相信 QB!”伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约. 这是 Modoka 的一个噩梦,也同时是上个轮回中所发生的事.为了使 ...

  5. 【Codeforces Round #428 (Div. 2) C】Journey

    [Link]:http://codeforces.com/contest/839/problem/C [Description] 给一棵树,每当你到一个点x的时候,你进入x的另外一每一个出度的概率都是 ...

  6. 邮件协议与port

          电子邮箱的协议有SMTP.POP2.POP3.IMAP4等.都隶属于TCP/IP协议簇,默认状态下.分别通过TCPport25.110和143建立连接.针对不同的用途和功能,我们在邮件se ...

  7. Bag of Features (BOF)图像检索算法

    1.首先.我们用surf算法生成图像库中每幅图的特征点及描写叙述符. 2.再用k-means算法对图像库中的特征点进行训练,生成类心. 3.生成每幅图像的BOF.详细方法为:推断图像的每一个特征点与哪 ...

  8. HDU 3232 &amp;&amp; UVA 12230 (简单期望)

    Crossing Rivers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  9. 安卓手机运行WINDOWS

    http://www.pcdiy.com.tw/detail/1974 我的ZenFone 2手机可以跑Windows啦! 就在台风来袭,有人正准备去泛舟的那天,国外的XDA论坛神人则是选择让自己的Z ...

  10. 1.13 Python基础知识 - 字典和集合

    一.字典 字典是一组键-值对的数据结构.每个键对应一个值.在字典中,键不能重复.根据键可以查询到值.字典是键和值的映射关系 字典的定义: 字典通过花括号中用逗号分隔的元素(键-值.键-值对使用冒号分隔 ...