最小子段和,最大子段和,最小正子段和

本文探讨了如何求解最大子段和、最小子段和以及重点介绍了最小正子段和的计算策略。通过计算前i位的累加和并排序,检查相邻元素之间的差值作为候选答案,最终选择最小的正子段和。记得在计算中包含特殊标记为-1和0的节点。

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

最大子段和比较好求解,就是一个dp标记走就可以了,当dp<0,让dp等于当前位,dp大于0就加上当前位就好。


最小子段和就是把所有的元素去相反数,然后在此基础上求一个最大子段和就好。


主要想说的是最小正子段和的求法,是先算前i位的累加和dp[i],并记录标记为i。

然后对所有的dp[i]进行小到大的排序,然后对两个相连的dp[i],如果后者的标记大于前者的标记,那么它们的差值是候选答案,然后选取候选答案最小的那个。

PS:注意要在里面加一个标记为-1的,和为0的节点。

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

/***********************
51nod 1065最小正子段和
***********************/

struct Node{
	__int64 val, flag;
};
Node node[50005];
__int64 N, num[50005];

bool comp(Node a, Node b)
{
	if(a.val == b.val)
		return a.flag > b.flag;
	return a.val < b.val;
}

int min(int a, int b)
{
	if(a < 0) return b;
	return a < b ? a : b;
}


void solve()
{
	for(int i = 0; i < N; i ++)
		cin>>num[i];

	//将每一项进行累加操作
	node[0].flag = -1, node[0].val = 0;
	for(int i = 1; i <= N; i ++){
		node[i].flag = node[i - 1].flag + 1;
		node[i].val = node[i - 1].val + num[i - 1];
	}
	//然后进行排序
	sort(node, node + N + 1, comp);

	int ans = -1;
	//当排序后,相连两项,它的后面一项的标记大于前面一项的标记时,它是候选答案之一,进行<span style="white-space:pre">	</span>//比较即可,注意加上一项为0的
	for(int i = 1; i <= N; i ++){
		if(node[i].flag > node[i - 1].flag){
			if(node[i].val - node[i - 1].val > 0)
				ans = min(ans, node[i].val - node[i - 1].val);
		}
	}
	cout<<ans<<endl;

}

int main()
{
	while(cin>>N){
		solve();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值