poj 2593 Max Sequence( 最大子段和 )

本文介绍了一种求解最大子段和问题的线性扫描算法,并提供了详细的实现步骤及核心代码。通过将数组分为两部分并分别计算各自的最大子段和来找到整个数组的最大子段和。

题目描述:

Give you N integers a1, a2 ... aN (|ai| <=1000, 1 <= i <= N). 
You should output S. 


思路:

将数组a[]从下标k处划分成两部分a[1-k]和a[k+1,N],用m1表示a[1-k]的最大字段和,m2表示a[k+1,N]的最大字段和,则 S = Max { m1, m2 } ( 其中k属于区间[2-N-1] ,k不能取1和N,因为题目中j<p)

通过正向遍历数组a求m1,逆向遍历数组a求m2,最后根据 S = Max { m1,m2 } 枚举k即可。

#include <iostream>
using namespace std;
const int INF = -0xfffffff;
const int Max = 100000;

// 对象
int n;
int a[Max+1];
int b[Max+2];
int m1[Max+2], m2[Max+2]; // m1[i]:Max sum of sub array [0,i] of a
                          // m2[i]:Max sum of sub array [i,n] of a
int maxSum; // res


int main()
{
	while( scanf( "%d", &n ) && n ) {
		m1[0] = m2[n+1] = INF;
		memset( b, 0, sizeof(b) );
		for( int i = 1; i <= n; ++ i ) {
			scanf( "%d", &a[i] );
			if( b[i-1] >= 0 )
				b[i] = b[i-1] + a[i];
			else 
				b[i] = a[i];
			m1[i] = b[i] > m1[i-1] ? b[i] : m1[i-1];
		}

		for( int i = n; i >= 1; -- i ) {
			if( b[i+1] >= 0 )
				b[i] = b[i+1] + a[i];
			else
				b[i] = a[i];
			m2[i] = b[i] > m2[i+1] ? b[i] : m2[i+1];
		}

		maxSum = INF;
		for( int i = 1; i < n; ++ i ) {
			if( m1[i] + m2[i+1] > maxSum )
				maxSum = m1[i] + m2[i+1];
		}
		printf( "%d\n", maxSum );
	}
	return 0;
}

写这篇解题报告想记一下求最大子段和的算法。

可以通过分治,也可以通过线性扫描。

我用的线性扫描法,想不通为什么网上都把这种方法成为动态规划。动归要满足最优子结构,貌似最大子段和问题没有子问题,也没出现子问题的重叠。。。




评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值