【u124】环状最大两段子段和
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】环状最大两段子段和的更多相关文章
- 洛谷 P1121 环状最大两段子段和 解题报告
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为\(A_1\)和\(A_N\)是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 第一行是一个正整数 ...
- P1121 环状最大两段子段和
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的 ...
- P1121 环状最大两段子段和(DP)
P1121 环状最大两段子段和 难度 提高+/省选- 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件 ...
- 洛谷P1121 环状最大两段子段和
题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的第一行是一个正整数N,表示了序列 ...
- 洛谷 P1121 环状最大两段子段和
https://www.luogu.org/problemnew/show/P1121 不会做啊... 看题解讲的: 答案的两段可能有两种情况:一是同时包含第1和第n个,2是不同时包含第1和第n个 对 ...
- luogu 1121 环状最大两段子段和
题目大意: 一个序列看做一个环 选两段数使它们和最大 思路: 定义一个dp数组i j 0/1 表示前i个取了连续的j段 0/1表示取不取第i个 但是因为看做一个环 首尾相接的情况可以看做是选三段,其中 ...
- Luogu1121:环状最大两段子段和
题面 传送门 Sol 两种情况 第一种就是类似\(***000***000***(0表示选)\),这个可以DP 设\(h[0/1/2/3][i]\)表示到第\(i\)位的状态: \(0\):表示还没选 ...
- luogu P1121 环状最大两段子段和
嘟嘟嘟 一道说难也难说简单也简单的dp题. 我觉得我的(有篇题解)做法就属于特别简单的. 平时遇到环的问题都是断环为链,但这道题给了一种新的思路. 观察一下,最后的答案无非就这两种:xxx--xx-- ...
- 洛谷 P1121 环状最大两段子段和 题解
每日一题 day57 打卡 Analysis 对于这个问题,由于分成了两个子序列,我们不妨就是枚举一下可能出现的情况: 无非就这两种: 1.+++++0000+++++0000++++ 2.0000+ ...
随机推荐
- Sublime10个经常使用插件
10. Package control Package control是必装插件,全部其它的插件和主题都能够通过它来安装. 希望它能出如今正式版默认包中. 首先參照以下的教程来安装Package Co ...
- java初探秘之推断输入的一串字符是否全为小写字母
import java.io.IOException; import java.util.*; public class Two { public static void main(String[] ...
- 【hoj】2160 bin packing 二分、贪心
这个题是在二分的题单上的,可是依据二分法写出来的会在oj上超时.依据题目以下给出的提示能够发现能通过贪心法每次都找最能满足的情况去填充每个包,这样就能保证使用的包的数量是最少的 二分法解法: #inc ...
- Qt 5.11的QChar、QString、QTextBoundaryFinder和双向文本算法现在完全兼容Unicode 10
本文翻译自:Qt 5.11 released 原文作者: Qt公司CTO兼Qt开源项目维护官Lars Knoll翻译校审:Richard.Hongfei.Haipeng 5月22日,我们提发布了Qt ...
- thinkphp图片处理
thinkphp图片处理 一.总结 1.参考手册:参考手册上面啥都有,只是这样业务逻辑不明显,所以看视频会很好,但是如果用编程的灵性(设计),那么其实会更加高效,但是看视频更快而且没那么枯燥,更高效把 ...
- js全选反选按钮实现
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Docker 搭建java+tomcat
1. 准备java和tomcat的软件包 jdk-7u79-linux-x64.tar.gz apache-tomcat-7.0.57.tar.gz 2. 编辑Dockerfile 文件 vim Do ...
- 1、DOM4J简介
1.DOM4J简介 DOM4J是 dom4j.org 出品的一个开源 XML 解析包.DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP. DOM4J ...
- l洛谷 P3926 SAC E#1 - 一道不可做题 Jelly
P3926 SAC E#1 - 一道不可做题 Jelly 题目背景 SOL君(炉石主播)和SOL菌(完美信息教室讲师)是好朋友. 题目描述 SOL君很喜欢吃蒟蒻果冻.而SOL菌也很喜欢蒟蒻果冻. 有一 ...
- jvm compile
>>>Making sec-files-win @ Thu Oct 17 20:34:02 CST 2013 ... >>>Making jgss-files @ ...