最大子段和
问题描述:
给定由n个整数(包含负整数)组成的序列a1,a2,…,an,求该序列子段和的最大值。
当所有整数均为负值时定义其最大子段和为0。
所求的最优值为:
例如,当(a1,a2, ……a7,a8)=(1,-3, 7,8,-4,12, -10,6)时,最大子段和为:
//最大子段和
//蛮力法 三重循环 复杂性O(n3)
#include<iostream>
using namespace std;
int MaxSum(int n, int* a, int& besti, int& bestj)
{
int sum = 0;
for (int i = 0; i <= n; i++) //以此计算a[i]~a[j]的子段和
{
for (int j = 0; j < n - 1; j++)
{
int thissum = 0;
for (int k = i; k <= j; k++)
thissum += a[k];
if (thissum > sum)
{
sum = thissum;
besti = i;
bestj = j;
}
}
}
return sum;
}
//算法改进 复杂度变为O(n2)
int MaxSum2(int n, int* a, int& besti, int& bestj)
{
int sum=0;
for (int i = 0; i <= n - 1; i++)
{
int thissum = 0;
for (int j = i; j <= n - 1; j++)
{
thissum += a[j];
if (thissum > sum)
{
sum = thissum;
besti = i;
bestj = j;
}
}
}
return sum;
}
//分治方法
int MaxSubSum(int a[], int left, int right)
{
int sum = 0;
if (left == right)
sum = a[left] > 0 ? a[left] : 0;
else {
//求左边最大和
int center = (left + right) / 2;
int leftsum = MaxSubSum(a, left, center);
int rightsum = MaxSubSum(a, center + 1, right);
int s1 = 0;
int lefts = 0;
for (int i = center; i >= left; i--)
{
lefts += a[i];
if (lefts > s1)
s1 = lefts;
}
//求右边最大和
int s2 = 0;
int rights = 0;
for (int i = center + 1; i <= right; i++)
{
rights += a[i];
if (rights > s2)
s2 = rights;
}
sum = s1 + s2;
if (sum < leftsum)
sum = leftsum;
if (sum < rightsum)
sum = rightsum;
}
return sum;
}
int main()
{
int a[6] = { -2,11,-4,13,-5,-2 };
int sum0 = MaxSum(6, a, a[0], a[5]);
cout << sum0 << endl;
int sum1 = MaxSum2(6, a,a[0],a[5]);
cout << sum1<<endl;
int sum2 = MaxSubSum(a,0,5 );
cout << sum2;
}
#include<iostream>
using namespace std;
#define NUM 101
int a[9] = { 0,1,-3,7,8,-4,12,-10,6 };
//计算最大字段和的动态规划算法
int MaxSum(int n)
{
int sum = 0; //最大子段和
int b = 0; //1-j的最大子段和,因为无需保留其它结果,所以没必要定义数组
for (int i = 1; i <= n; i++)
{
if (b > 0)
b += a[i];
else
b = a[i];
if (b > sum)
sum = b;
}
return sum;
}
//计算最大子段和的动态规划算法的最优解
int MaxSum2(int n, int besti, int bestj)
{
int sum = 0;
int b = 0;
int begin = 0;
for (int i = 1; i <= n; i++)
{
if (b > 0)
b += a[i];
else {
b = a[i];
begin = i;
}
if (b > sum)
{
sum = b;
besti = begin;
bestj = i;
}
}
return sum;
}
int main()
{
int sum = MaxSum(8);
cout << sum;
return 0;
}