Description
Learn, learn and learn again — Valera has to do this every day. He is studying at mathematical school, where math is the main discipline. The mathematics teacher loves her discipline very much and tries to cultivate this love in children. That's why she always gives her students large and difficult homework. Despite that Valera is one of the best students, he failed to manage with the new homework. That's why he asks for your help. He has the following task. A sequence of n numbers is given. A prefix of a sequence is the part of the sequence (possibly empty), taken from the start of the sequence. A suffix of a sequence is the part of the sequence (possibly empty), taken from the end of the sequence. It is allowed to sequentially make two operations with the sequence. The first operation is to take some prefix of the sequence and multiply all numbers in this prefix by - 1. The second operation is to take some suffix and multiply all numbers in it by - 1. The chosen prefix and suffix may intersect. What is the maximum total sum of the sequence that can be obtained by applying the described operations?
Input
The first line contains integer n (1 ≤ n ≤ 105) — amount of elements in the sequence. The second line contains n integers ai ( - 104 ≤ ai ≤ 104) — the sequence itself.
Output
The first and the only line of the output should contain the answer to the problem.
Sample Input
3 -1 -2 -3
6
5 -4 2 0 5 0
11
5 -1 10 -5 10 -2
18
题意:
将某段前缀和某段后缀同时乘以-1或者不乘,使整个数列和达到最大值。
思路:
寻找数列中的最大子序列正数和(尽可能的找到一个最大的正数和,没有就为0,与最大子序列和有区别,区别在于子序列和可以为负数)max,未改变序列符号前的总和为sum,则需要改变符号部分的和为sum-max,改变符号后为max-sum,最后将最大子序列正数和max 与 改变符号部分和max-sum相加,那么得出来的数就是所要求的最大值 2*max-sum。
AC:
#include<stdio.h> int main() { int N,i,number[100005],sum=0,max=0,sum1=0; scanf("%d",&N); for(i=0;i<N;i++) { scanf("%d",&number[i]); sum+=number[i]; //为改变符号时候的总和 } for(i=0;i<N;i++) { sum1+=number[i]; if(sum1<0) sum1=0; //如果算到此时的和为小于0的数,则重新开始计算 //这里是用sum1来比较是否小于0 //一开始写的时候是if(number[i]<0) continue; //因为单纯只以为这是忽略序列前缀小于0的操作,如果后面有在正数之间存在负数,则也会被continue掉 //那么单纯用number[i]来判断是否小于0的话,意思就是说,凡是小于0的数都不加上去,加上去的都是整数 //那么得出来的数不是代表最大连续子序列正数和,而是序列的正数和 if(sum1>max) max=sum1; //如果和不小于0的话,那就是一个正数,每次得出来的正数和与max比较 //循环结束后就会得到最大连续子序列正数和了 } //max为最大连续子序列正数和 printf("%d\n",2*max-sum); return 0; }
Why:(Details in“最大连续子序列正数和求法”)
for(i=0;i<N;i++) { sum1+=number[i]; if(sum1<0) sum1=0; if(sum1>max) max=sum1; }
为什么不能写成这样:
i=0; while(number[i]<0) i++; //先忽略前面的负数项,从正数项开始求 for(i;i<N;i++) { sum1+=number[i]; if(sum1>max) max=sum1; }
Improve:
参考别人的写法,发现可以把代码写得更加简短。
#include<stdio.h> int main() { int N,i,sum=0,number,max=0,summax=0; scanf("%d",&N); for(i=1;i<=N;i++) { scanf("%d",&number); sum+=number;//求原来的和 summax+=number;//求最大子序列和 if(summax<0) summax=0; if(summax>max) max=summax; //只要summax不小于0,那就不会进行清0操作 //summax只要大于0都会继续相加,无论number是正还是负,因为下面还会有比较操作,所以number操作不影响最大值 //模拟max[i]=max[i-1]>=0?max[i-1]+number[i]:number[i]的过程 //如果max[i-1]小于0则令max[i-1]=0,循环结束到下一项就是max[i]+=number[i] //如果max[i-1]大于等于0,则继续叠加,循环结束后就是max[i]=max[i-1]+number[i]; } printf("%d\n",2*max-sum); } //不需要开个数组来保存数据,直接输入一个数就加和一个数,判断一个数
总结:
理解很多次才把题目给理解了……一开始以为是前缀和后缀的数量是一样的,思考了很久才发现一直都理解错了。既然前缀和后缀改变符号的数量是任意的,通过改变或者不改变来使整个序列和达到最大值。再进一步思考,为什么要改变这个这个前缀和后缀呢,是因为这些要改变的这些数全部加起来是个负数,在原本已经是“最大连续子序列正数和”的基础上再加上这些“前缀和后缀”的话,那就会使这个子序列和减少了。所以要增加这个最大连续子序列正数和的话,就要将这些前缀和后缀变成正数,所以就要乘以-1,再加上这个序列的最大连续子序列正数和来求得这整个数列的最大值。
既然这样,那问题就转化为求这个序列的最大连续子序列正数和了。虽然想到了这一步,但是代码实现方面还是很弱,发现了自己写的代码为什么不对,为什么要那样写才可以求出最大子序列。理解了之后又可以进一步的优化代码,不需要开数组来存储数据,而且也只需要循环一次数组就可以了。
相关推荐
用于施工安全设施计算,施工方案,技术交底,应急预案、可以计算模板支架体系,高支模,地基承载力,边坡承载力,卸料平台安全计算等,网络收集,请支持正版
这个压缩包"autoitV3.2.13.7.rar"包含了AutoIt的特定版本——V3.2.13.7,该版本可能包含了一些修复、增强功能或优化。特别的是,这个版本是汉化的,意味着所有文档和界面都已经翻译成了中文,对于中文用户来说,学习...
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 ...
标题“Location-cleaned13.7.rar”暗示我们可能正在处理一个与地理位置数据清理相关的iOS项目,文件已经压缩成RAR格式。RAR是一种流行的压缩格式,用于减少文件大小以便于存储和传输。描述中的内容与标题相同,这...
这个压缩包文件"opencv-2.4.13.7.zip"包含的是OpenCV 2.4.13.7版本,这是一个相对早期但仍然广泛使用的版本,尤其对于那些对稳定性有特定需求的项目。在OpenCV 2.4系列之后,OpenCV进入了3.x时代,引入了更多先进的...
在版本13.7.9中,Draw.io进一步提升了用户体验,提供了一系列增强和改进,使绘图过程更为流畅。 首先,Draw.io的核心功能在于其丰富的图形库。用户可以找到各种各样的形状,包括但不限于流程图、组织结构图、思维...
"xcode真机 13.7.zip"这个压缩包很可能包含了一个特定版本为13.7的Xcode真机调试所需的组件和资源。在iOS应用开发中,真机调试是一个重要的环节,因为模拟器虽然可以模拟大部分设备行为,但某些功能和性能问题只有在...
北京鼎汉通技术有限公司无线测温说明书_13.7.10.doc
安卓UC浏览器V13.7.5.1321国际2024清爽版 UC 浏览器谷歌商店版,可以切换为繁体中文,相比国内版本,干净得有点过分。主页无新闻推送 语言设置: 点击底部菜单>设置语言选择繁体中文即可
高中物理 13.7.8 光的颜色 色散 激光课件 新人教选修34 .ppt
【朋友圈广告助手最新版13.7.0(1).rar】是一款专为微信小程序设计的广告管理工具,主要用于帮助用户更加高效地管理和优化在微信朋友圈投放的广告。这款工具的最新版本13.7.0引入了新的特性和改进,以适应不断变化的...
本资源包"iOS真机调试资源_13.7.zip"专为iOS 13.7版本设计,提供了一套完整的工具和配置,以便开发者能够有效地在装有iOS 13.7系统的iPhone或iPad上进行调试工作。 首先,我们需要了解Xcode。Xcode是Apple官方提供...
SDK 13.7.zip 是一个与Xcode相关的软件开发工具包,主要针对的是iOS、iPadOS以及其他基于Apple平台的应用程序开发。Xcode是Apple官方提供的集成开发环境(IDE),它包含了编写、测试和调试软件所需的所有工具。SDK,...
资源分类:Python库 所属语言:Python 资源全名:pyginx-0.1.13.7.7-cp36-cp36m-macosx_10_13_x86_64.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
版本13.7.0的免安装特性使得用户无需复杂安装过程即可快速启动并使用。这个压缩包包含了ShareX的主要组件和辅助库,方便用户直接解压使用。 1. **截图功能**:ShareX的核心功能之一就是提供高质量的截图工具。它...
这款软件的最新版本为13.7.9,特别针对Windows用户提供了无需安装的版本,即"draw.io-13.7.9-windows-no-installer.exe",方便用户直接运行,无需担心系统冲突或繁琐的安装步骤。 流程图是一种图形化表示工作流程或...
《Xcode iOS 设备支持库:DeviceSupport 13.7 深度解析》 在iOS开发领域,Xcode是不可或缺的工具,它包含了众多用于构建、测试和部署iOS应用的功能。其中,`DeviceSupport`目录对于开发者来说至关重要,因为它包含...
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 ...