O(n^2)
#include<iostream>
#define N 10000
int main()
{
int k , start=0 , end=0 , max_sum=-1,sum;
int i ,j;
int tag=0;//判断是否都是负数,tag=0都是负数
int a[N];
scanf("%d",&k);
for(i=0;i<k;i++){
scanf("%d",&a[i]);
if(a[i]>=0) tag=1;
}
if(tag==0)
printf("%d %d %d\n",tag,a[0],a[k-1]);
else
{
for(i=0;i<k;i++)
{
sum=0;
for(j=i;j<k;j++)
{
sum+=a[j];
if(sum>max_sum)
{
start=i;
end=j;
max_sum=sum;
}
}
}
printf("%d %d %d\n",max_sum,a[start],a[end]);
}
return 0;
}O(n)
最大子列和非负,保存第 i 项的前n项大于等于零的和,若和小于零则从 i 重新开始计算子列和,同时用数组start保存开始项
#include<iostream>
#define N 1000
int main()
{
int a[N]={0};
int sum[N]={0},start[N]={0};
int k,i;
scanf("%d",&k);
for( i=0;i<k;i++)
scanf("%d",&a[i]);
sum[0]=a[0];
start[0]=0;
for( i=1;i<k;i++)
{
if(sum[i-1]>=0)
{
sum[i]=sum[i-1]+a[i];
start[i]=start[i-1];
}
else
{
sum[i]=a[i];
start[i]=i;
}
}
int max=sum[0];
int index;
for( i=1;i<k;i++)
{
if(max<sum[i])
{
index=i;
max=sum[i];
}
}
if(max<0)
printf("0 %d %d\n",a[0],a[k-1]);
else
printf("%d %d %d\n",sum[index],a[start[index]],a[index]);
return 0;
}
本文介绍了两种求解最大子列和问题的算法实现:一种时间复杂度为O(n^2)的方法,通过双重循环遍历所有可能的子列;另一种更高效的时间复杂度为O(n)的方法,利用动态规划思想,仅需一次遍历即可找出最大子列和及其起始与结束位置。
353

被折叠的 条评论
为什么被折叠?



