问题介绍:
在一个有限序列,任意连续的序列的和的最大值,记为最大子段和。
直接算法:
确切的说是改进后的直接算法,时间复杂度是O(n^2)
动态规划算法
规定当子段和为负整数时,字段和为0;
时间复杂度是O(n);
改进的直接算法代码:
/* * 求最大子段和的原始版的改进版 * 时间复杂度O(n^2) */
#include <iostream>
using namespace std;
MaxSubSum(int n ,int a[], int &besti,int &bestj){
int sum=0;
int i,j;
for(i=0;i<n;i++){
int thissum=0;
for(j=i;j<n;j++){//在遍历的时候顺便把临时最大子段和给求出来
thissum+=a[j];
if(thissum>sum){
sum=thissum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int main(){
int besti,bestj;
besti=bestj=0;
int a[5]={-1,2,3,-4,1};
cout<<MaxSubSum(5,a,besti,bestj)<<endl;
cout<<"("<<besti<<","<<bestj<<")"<<endl;
return 0;
}
动态规划算法代码:
/* *动态规划求最大子段和 * besti,bestj记录最大子段的开始下标和结束下标 * 时间复杂度O(n) * */
#include <iostream>
using namespace std;
MaxSubSum(int n,int a[],int &besti,int &bestj){
int sum =0,b=0;
int j;
for(j=0;j<n;j++){
b+=a[j];
if(b<0){
b=0;
besti=j+1;//一旦b<0,抛弃前面的结果,把j的下一个位置记录下来
bestj=j+1;
}
if(b>sum){
sum=b;
bestj=j;//bestj跟着sum更新而更新
}
}
return sum;
}
int main(){
int besti,bestj;
besti=bestj=0;
int a[5]={8,-1,3,2,-1};
cout<<MaxSubSum(5,a,besti,bestj)<<endl;
cout<<besti<<" "<<bestj<<endl;
}