题目来自网络
题目:给出一数组,求出最大连续子序列之和。
思想(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; }