求最大子列和问题
题目
给定K个整数组成的序列{ N1, N2, …, NK},“连续子列”被定义为{ Ni, Ni+1, …, Nj },其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。
第一种方法(最不好)
在此方法中用了三个循环,第一层是子列左端,第二层是子列右端,里层为子列的求和。T(N)= O(N^3)
int ThisSum , MaxSum = 0;
int i,j,k;
for( i = 0; i < N; i++) /*i是子列左端位置*/
{
for( j = i; j < N; j++) /* J是子列右端位置*/
{
ThisSum = 0; /*ThisSum是从A[i]到A[j]的子列和*/
for( k = i; k <= j; k++)
ThisSum += A[k];
if( ThisSum > MaxSum ) /*如果刚得到的这个子列和更大*/
MaxSum = ThisSum; /*则更新结果*/
}
}
第二种方法
其实就是把最里层的循环去掉
int ThisSum , MaxSum = 0;
int i,j,k;
for( i = 0; i < N; i++) /*i是子列左端位置*/
{
ThisSum = 0; /*ThisSum是从A[i]到A[j]的子列和*/
for( j = i; j < N; j++) /* J是子列右端位置*/
{
ThisSum += A[j];/*对于相同的i,不同的j,只要在j-i次循环的基础上累加1项即可*/
if( ThisSum > MaxSum ) /*如果刚得到的这个子列和更大*/
MaxSum = ThisSum; /*则更新结果*/
}
}
第三种:分治法
第四种:在线处理(最好)
int n,m,maxsum=0,zisum=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>m;
zisum += m; /*向右累加*/
if(zisum>maxsum)
{
maxsum=zisum; /* 发现了更大的子列则更新现在的结果*/
}
else if(zisum<0) /* 若当前子列和为负*/
{
zisum=0; /* 不可能使后面的部分和增大,抛弃之*/
}
}
cout<<maxsum;