(1)最基础的方法。O(n^2)
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int main()
{
int k=1,T;
scanf("%d",&T);
while(k<=T)
{
int N;
scanf("%d",&N);
int *data=(int *)malloc(sizeof(int)*N);
for(int i=0;i<N;i++)
scanf("%d",&data[i]);
int Max=INT_MIN,sum=0;
int left,right;
for(int i=0;i<N;i++)
{
sum=0;
for(int j=i;j<N;j++)
{
sum+=data[j];
if(sum>Max)
{
Max=sum;
left=i;
right=j;
}
}
}
printf("Case %d:\n",k);
printf("%d %d %d\n",Max,left+1,right+1);
if(k!=T) printf("\n");
free(data);
k++;
}
return 0;
}
(2)分治
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
typedef struct Node
{
int Sum;
int l_index;
int r_index;
}Node;
Node solve_mid(int *data,int low,int high)
{
Node Max;
int l_sum=INT_MIN,r_sum=INT_MIN,mid=(low+high)/2,sum=0;
for(int i=mid;i>=low;i--)
{
sum+=data[i];
if(sum>=l_sum)//这里应该是 >=,因为是向左寻找,并且题目要求输出 第一个 满足要求的结果
{
l_sum=sum;
Max.l_index=i;
}
}
sum=0;
for(int i=mid+1;i<=high;i++)
{
sum+=data[i];
if(sum>r_sum)
{
r_sum=sum;
Max.r_index=i;
}
}
Max.Sum=l_sum+r_sum;
return Max;
}
Node solve(int *data,int low,int high)
{
if(low==high) {//这个地方需不需要返回下标的值?
Node Max;
Max.Sum=data[low];
Max.l_index=low;
Max.r_index=high;
return Max;
}
int mid=(low+high)/2;
Node ret1=solve(data,low,mid);
Node ret2=solve_mid(data,low,high);
Node ret3=solve(data,mid+1,high);
Node Max;
if(ret1.Sum>=ret2.Sum) Max=ret1;
else Max=ret2;
if(Max.Sum<ret3.Sum) Max=ret3;
return Max;
}
这里下标值的返回也可以采用引用
(3)线性
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
int main()
{
int k=1,T;
scanf("%d",&T);
while(k<=T)
{
long N;
scanf("%d",&N);
int data[100001];
for(long i=0;i<N;i++)
scanf("%d",&data[i]);
long Max=INT_MIN,left,right,temp=0;
long sum=0;
for(long i=0;i<N;i++)
{
sum+=data[i];
if(sum>Max)
{
Max=sum;
left=temp;//假设最大子序列从下标为 0 的元素开始
right=i;//实时更新最大子序列的 最大右下标值
}
//一个子序列必然是以正数开头的,因为如果以负数开头,那么去掉这个子序列,那得到一个更优解
if(sum<0)
{
sum=0;
temp=i+1;//啦啦
}
}
printf("Case %d:\n",k);
printf("%ld %ld %ld\n",Max,left+1,right+1);
if(k!=T) printf("\n");
k++;
}
return 0;
}
思路三参考代码来源:https://blog.youkuaiyun.com/wptad/article/details/1709598