洛谷 P1121 环状最大两段子段和
https://www.luogu.org/problemnew/show/P1121
不会做啊。。。
看题解讲的:
答案的两段可能有两种情况:一是同时包含第1和第n个,2是不同时包含第1和第n个
对于第二种可以先求出f[i],g[i]分别表示1..i和i..n的最大子段和,然后枚举断点解决
对于第一种可以转化成找到“序列上最小两段字段和“去掉,这可以用第二种的方法解决;不过注意这个”序列上最小两段字段和“长度必须<=n-2(因为要剩下至少2个元素),需要一些特判
另外,话说此题居然还能用线段树维护...
(然而数据弱,仍然不知道以下代码是不是对的)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
#define int ll
struct pii
{
int fi,se;
pii():fi(),se(){}
pii(int a,int b):fi(a),se(b){}
};
pii max1(const pii &a,const pii &b)
{
return (a.fi<b.fi||(a.fi==b.fi&&a.se>b.se))?b:a;
}
pii min1(const pii &a,const pii &b)
{
return (a.fi<b.fi||(a.fi==b.fi&&a.se<b.se))?a:b;
}
int a[];
pii f1[],g1[],f2[],g2[];
int n,a1,a2,sum;
int calc(int p)
{
if(p==)
{
return g2[].se==n- ? g2[].fi-max(a[],a[n]) : g2[].fi;
}
else if(p==n)
{
return f2[n-].se==n- ? f2[n-].fi-max(a[],a[n-])
: f2[n-].fi;
}
else
{
return f2[p-].se+g2[p+].se==n-
? f2[p-].fi+g2[p+].fi - max(max(a[],a[p-]),
max(a[p+],a[n]))
: f2[p-].fi+g2[p+].fi;
}
}
signed main()
{
int i;pii t;
scanf("%lld",&n);
if(n<=) exit(-);
for(i=;i<=n;++i)
{
scanf("%lld",&a[i]);
sum+=a[i];
}
f1[]=pii(a[],);
t=pii(a[],);
if(t.fi<=) t=pii(,);
for(i=;i<=n;++i)
{
t.fi+=a[i];++t.se;
f1[i]=max1(f1[i-],t);
if(t.fi<=) t=pii(,);
}
g1[n]=pii(a[n],);
t=pii(a[n],);
if(t.fi<=) t=pii(,);
for(i=n-;i>=;--i)
{
t.fi+=a[i];++t.se;
g1[i]=max1(g1[i+],t);
if(t.fi<=) t=pii(,);
}
f2[]=pii(a[],);
t=pii(a[],);
if(t.fi>=) t=pii(,);
for(i=;i<=n;++i)
{
t.fi+=a[i];++t.se;
f2[i]=min1(f2[i-],t);
if(t.fi>=) t=pii(,);
}
g2[n]=pii(a[n],);
t=pii(a[n],);
if(t.fi>=) t=pii(,);
for(i=n-;i>=;--i)
{
t.fi+=a[i];++t.se;
g2[i]=min1(g2[i+],t);
if(t.fi>=) t=pii(,);
}
a1=f1[].fi+g1[].fi;
for(i=;i<=n-;++i)
a1=max(a1,f1[i].fi+g1[i+].fi);
a2=calc();
for(i=;i<=n;++i)
a2=min(a2,calc(i));
printf("%lld",max(a1,sum-a2));
return ;
}
洛谷 P1121 环状最大两段子段和的更多相关文章
- 洛谷 P1121 环状最大两段子段和 解题报告
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为\(A_1\)和\(A_N\)是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 第一行是一个正整数 ...
- 洛谷P1121 环状最大两段子段和
题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的第一行是一个正整数N,表示了序列 ...
- 洛谷 P1121 环状最大两段子段和 题解
每日一题 day57 打卡 Analysis 对于这个问题,由于分成了两个子序列,我们不妨就是枚举一下可能出现的情况: 无非就这两种: 1.+++++0000+++++0000++++ 2.0000+ ...
- P1121 环状最大两段子段和
P1121 环状最大两段子段和 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件maxsum2.in的 ...
- P1121 环状最大两段子段和(DP)
P1121 环状最大两段子段和 难度 提高+/省选- 题目描述 给出一段环状序列,即认为A[1]和A[N]是相邻的,选出其中连续不重叠且非空的两段使得这两段和最大. 输入输出格式 输入格式: 输入文件 ...
- luogu P1121 环状最大两段子段和
嘟嘟嘟 一道说难也难说简单也简单的dp题. 我觉得我的(有篇题解)做法就属于特别简单的. 平时遇到环的问题都是断环为链,但这道题给了一种新的思路. 观察一下,最后的答案无非就这两种:xxx--xx-- ...
- 【u124】环状最大两段子段和
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 给出一段环状序列,即认为A[1]和A[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\):表示还没选 ...
随机推荐
- eclipse配置SVN
1.设置 maven 工程svn忽略target 最新maven写法忽略的文件,还需忽略target.*/logs. Windows -> Preferences -> Team -> ...
- Redis穿透问题解决方案
缓存穿透 缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有.这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空.这样请求就绕过缓存直接查数据库,这也是经常提的 ...
- 千锋很火的SpringBoot实战开发教程视频
springboot是什么? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...
- 如何强制ffmpeg编码时输出一个关键帧
http://blog.csdn.net/ashlingr/article/details/7829429 如何强制ffmpeg编码时输出一个关键帧 如何强制ffmpeg编码时输出一个关键帧 AV ...
- ubuntu的ufw如何开放特定端口?
ubuntu的ufw如何开放特定端口? 1.安装 sudo apt-get install ufw 2.开启 sudo ufw enable 默认关闭外部访问 sudo ufw default den ...
- Java 发送Get和Post请求
package com.htpt.superviseServices.dm.util; import java.io.BufferedReader; import java.io.IOExceptio ...
- python 二分法例子及冒泡排序
#!/usr/bin/env python #-*- coding:utf-8 -*- def binary_search(source_data,find_nu): mid = len(source ...
- BZOJ_2369_区间_决策单调性
BZOJ_2369_区间_决策单调性 Description 对于一个区间集合 {A1,A2……Ak}(K>1,Ai不等于Aj(i不等于J),定义其权值 S=|A1∪A2∪……AK|*|A1 ...
- 一:MetaMq集群中单个节点的安装配置示意图
MetaMQ集群一个节点的安装和配置示意图[1]:下载metaMQ的安装包
- C++之运算符重载(前置++和后置++)
今天在阅读<google c++ 编程风格>的文档的时候,5.10. 前置自增和自减:有一句话引起了我的注意: 对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.,理 ...