题目来自网络
题目:给出一数组,求出最大连续子序列之和。
思想(1):
(1)负数是不能作为最大子序列的第一个元素的(当然可以是中间区间的某个元素)。
(2)类似地,任何区间之和为负的子序列不可能是最大子序列的前缀。(即,该序列不可能是最大子序列的起始序列)
代码:
#include <iostream>
#include <assert.h>
using namespace std;
/*
思想:负数是不能作为最大子序列的第一个元素的(当然可以是中间区间的某个元素)。
类似地,任何区间之和为负的子序列不可能是最大子序列的前缀
(即,该序列不可能是最大子序列的起始序列)
*/
int MaxSubSum(int arr[],int nStart,int nEnd)
{
assert(arr != NULL && nStart <= nEnd && nStart >= 0 && nEnd >= 0);
int nSubSum = arr[nStart];
int nMaxSubSum = arr[nStart]; //不能写成0,否则不适合序列全是负数的情况
int nCurStart = nStart;
int nMaxStart = nStart;
int nMaxEnd = nStart;
for (int i = nStart + 1;i <= nEnd;i++)
{
if (nSubSum < 0)
{
nSubSum = arr[i];
nCurStart = i;
}
else
{
nSubSum += arr[i];
}
if (nSubSum > nMaxSubSum)
{
nMaxSubSum = nSubSum;
nMaxStart = nCurStart;
nMaxEnd = i;
}
}
cout<<"下标区间:"<<nMaxStart<<" - "<<nMaxEnd<<endl;
return nMaxSubSum;
}
int main()
{
int arr[8] = {4,-3,5,-2,-1,2,6,-2};
cout<<MaxSubSum(arr,0,7)<<endl;
int arr1[8] = {4,-3,5,-11,4,-2,5,-2};
cout<<MaxSubSum(arr1,0,7)<<endl;
int arr2[8] = {-3,-5,-8,-2,-11,-12,-13,-1};
cout<<MaxSubSum(arr2,0,7)<<endl;
int arr3[8] = {-1,0,-4};
cout<<MaxSubSum(arr3,0,2)<<endl;
int arr4[4] = {-1,2,-4,1};
cout<<MaxSubSum(arr4,0,3)<<endl;
system("pause");
return 1;
}
注意:
(1)如果题目要求是,结果和为负数,则直接返回0.
此时,只需要修改变量nMaxSubSum,令其初始化时 nMaxSubSum = 0。
(2)这里的方法不能求出子序列的具体位置
思路(2)
利用DP来做,这里使用一维数组保存状态,也可以使用一个变量保存最大值,代码略。
#include <iostream>
#include <assert.h>
using namespace std;
/*
F[i]:表示从某个元素开始且第i个元素结尾的子数组最大和
F[i] = F[i - 1] + nArr[i]; i > 0 && F[i - 1] > 0
F[i] = nArr[i];i = 0 || F[i - 1] <= 0 */
int MaxSubSum(int nArr[],int nLen)
{
int nCurStart = 0;
int nStart = 0;
int nEnd = 0;
int F[100];
int nMaxSum = nArr[0];
F[0] = nArr[0];
for (int i = 1;i < nLen;i++)
{
if (F[i - 1] > 0)
{
F[i] = F[i - 1] + nArr[i];
}
else
{
F[i] = nArr[i];
nCurStart = i;
}
if (F[i] > nMaxSum)
{
nMaxSum = F[i];
nEnd = i;
nStart = nCurStart;
}
}
cout<<"下标区间:"<<nStart<<" - "<<nEnd<<endl;
return nMaxSum;
}
int main()
{
int nArr[8] = {4,-3,5,-2,-1,2,6,-2};
int nLen = 8;
// int nArr[6] = {-2,11,-4,13,-5,-2};
// int nLen = 6;
// int nArr[8] = {-1,-1,-1,-1,-1,-1,-1,-1};
// int nLen = 8;
// int nArr[6] = {-1,-2,0,1,-4,10};
// int nLen = 6;
cout<<MaxSubSum(nArr,nLen)<<endl;
system("pause");
return 1;
}