最小和 --- 求一类数字区间问题

本文介绍了如何利用前缀和解决两类数字区间问题:寻找序列中连续子序列和的最小绝对值及最大和。通过设置s[i]表示前i个数字之和,并对前缀和进行排序,可以找到最小绝对值的和以及最长序列的长度。给出的代码实现了快速排序算法来处理这个问题,但未经过充分测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看题目:

 

1.

 

N个数排成一排,你可以任意选择连续的若干个数,算出它们的和。问该如何选择才能使得和的绝对值最小。

如:N=8时,8个数如下:

1    2    3    4    5    6    7    8

-20   90  -30   -20   80  -70  -60   125

如果我们选择144个数,和为20,还可以选择683个数,和为-5|-5|=5,该方案获得的和的绝对值最小。

输入格式:

第一行输入N,表示数字的个数。接下来N行描述这N个数字。

 

输出格式:

第一行输出一个整数,表示最小绝对值的和,第二行包含一个整数表示形成该绝对值和最长序列的长度。

 

 

1<= N<=100000


 

或者

 

2.

 

N个数围成一圈,要求从中选择若干个连续的数(注意每个数最多只能选一次)加起来,问能形成的最大的和。

 

N<=100000


 

这样的题目,一般可以用前缀和来做。

 

以第一题为例子

 

我们设s[i]为前i个数字之和.那么s[i]-s[j] (i>j) 就为j+1到i的数字之和。这样我们就可以任意求出一段区间的和是多少。

 

在利用题目的条件,看看能不能利用前缀和的性质。

 

还是对于第一题。我们把得到的前缀和进行排序,那么可以知道min{ abs( s[i]-s[i-1] ) }就是答案。注意排序前加入一个s[0]=0,因为s[i]-s[j] (i>j) 表示j+1到i的数字之和

 

因为前缀和排序后。以i为一段的区间的最小绝对值一定是 min{ abs( s[n]-s[n-1] ),abs( s[n] - s[n+1] ) } 这里的n是i在排序以后的位置

 

用快排nlongn就能排好,加上O(n)的扫描。

 

下面是自己写的第一题的代码,没有测试数据(手上的测试数据有错误)。。 大家权当参考吧

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值