环形数组 最大子段和 dp

题目链接:https://nanti.jisuanke.com/t/36118

环形数组的连续最大子段和,有两种情况。

1.最大和的这个子段没有包含头尾。所以直接dp[i] = max(dp[i-1]+a[i],a[i])

2.最大和的这个子段包含了头尾。这个时候,最大和 = 累积和 - 连续子段最小和。

然后比较两种情况的大小,输出大的那一个就行。

#include <bits/stdc++.h>
#define ms(a) memset(a,0,sizeof(a))
#define ll long long
using namespace std;
const int M = 1e5+9;
ll a[M],b[M],dp[M];
ll sum = 0,mx = 0,mi = 0;

int main()
{
	int n;
	ms(dp);
	scanf("%d",&n);
	for(int i = 0; i < n; i++)
	{
		scanf("%lld",&a[i]);
		sum += a[i];
		b[i] = -a[i];
	}

	for(int i = 0; i < n; i++)
	{
		dp[i] = max(a[i],dp[i-1]+a[i]);
		mx = max(mx,dp[i]);
	}
	ms(dp);
	for(int i = 0; i < n; i++)
	{
		dp[i] = max(b[i],b[i]+dp[i-1]);
		mi = max(mi,dp[i]);
	}
	ll ans = max(sum+mi,mx);
	printf("%lld\n",ans);
	return 0;
}

原文地址:https://www.cnblogs.com/stul/p/10348764.html

时间: 2024-10-11 21:07:20

环形数组 最大子段和 dp的相关文章

51Nod 1050 循环数组最大子段和 | DP

Input示例 6 -2 11 -4 13 -5 -2 Output示例 20 分析: 有两种可能,第一种为正常从[1 - n]序列中的最大子字段和:第二种为数组的total_sum - ([1-n]序列中的最短序列和) 最后结果为 max { 第一种, 第二种}. 对于第二种: 循环数组求最大子段和,可能出现中间的一部分不要,要两边的数.比如:-1 4 -1 -5 5 -2 1 -1 3,他的最大子段和就为 左边的-1 4加上右边的5 -2 1 -1 3,也就是,去掉1 -5这一段后的结果.而

51nod 1050 循环数组最大子段和【环形DP/最大子段和/正难则反】

1050 循环数组最大子段和 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题  收藏  关注 N个整数组成的循环序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的连续的子段和的最大值(循环序列是指n个数围成一个圈,因此需要考虑a[n-1],a[n],a[1],a[2]这样的序列).当所给的整数均为负数时和为0. 例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13.和为20. Input 第1

结对开发之环形数组

一.题目与要求 题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n) 二.设计思路 1.在上一次求一维数组最大子数组的问题上,进行拓展,继续使用类似的求和方法 2.应题目要求,这次的一位数组要首尾

环形数组最大子数组的和及位置

题目: 求环形数组中最大子数组的和及位置. 实验思路: 环形数组中最大子数组的和包括两种情况 1.最大子数组和不包括连接处 设计思想见上篇 2.最大子数组和包括连接处 最大子数组的和=数组的和-最小子数组的和 程序代码: 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int Array[100]; //定义数组 6 int length; //数组长度 7 for(length=0;;) //输入数组 遇到Ent

环形数组最大子数组之和

题目:返回一个整数数组中最大子数组的和.要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1],…… A[n-1],A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值. 合作伙伴:孟西鑫 博客地址:http://home.cnblogs.com/u/wanzitou/feed/blog/ 结对编程要求: 两人结对完成编程任务. 一人主要负责

软件工程——结对开发环形数组

一.题目: 返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如 果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思路 开始想的是用链表实现数组首尾相连,可是由于链表用着不太熟悉,便想了另一种算法: 当最大值未出现跨域是就按常规方法计算找

《团队项目开发之三对一维环形数组的求解》

设计思想:通过把数组的长度扩大为原来的一倍,相当于新数组是由对原来的数组重复了一遍后而组成的,这样保证了数组以环状的形式,按照数组中每个数字的位序依次对它们可能形成的最大子数组依次进行比较,这样保证了能够始终记录每次最大子数组的位置,以便随着程序的进行不断更新直至得到最终的最大子数组之和以及最大子数组的下标. 源代码: //求一个一维环形数组的最大子数组之和,并要求返回组成最大子数组的下标 //李敏,Apr 12th #include<iostream> #include <time.h

结对开发——求二维环形数组所有子矩阵最大和的问题

一.题目要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值. 要求时间复杂度为O(n)题目:返回一个二维整数数组中最大子数组的和. 二.解决思路: 由于上次我们做过求二维数组最大子矩阵和的问题,又做了求一维环状数组的子数组最大值问题,这次就在以前的基础上进行修改,先对二维数组进行了重构,形成一个环状二维数组,然后再用求二维数组子矩阵最大和的方法求得最终结果.

数组连续最大子和及环形数组最大子和

问题1: /*求连续子数组的最大和: * 设curSum为当前子数组(ai, ai+1, ......, aj)的和 * sum存放到目前为止子数组和的最大值 * 1. cursum+ai>0; cursum=cursum+ai * 2. cursum+ai<=0; cursum=ai; */ 1 int maxsubarr(vector<int> &a) 2 { 3 if(a.size()==0) 4 return 0; 5 int sum=0x80000000; //s