算法一:穷举—繁
#include<stdio.h>
//求最大值序列和一
int main()
{
int sum,num;
int n,i,j,k;
scanf("%d",&n);//输入序列总数
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//输入序列
}
sum=0;//最大子序列和置0
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
num=0;//临时子序列和比较完归0
for(k=i;k<=j;k++)//用三层for循环来遍历所有序列和的可能
{
num+=a[k];//求出所有序列和
}
if(num>sum)
{
sum=num;//比较得出最大值
}
}
}
printf("%d",sum);//输出最大值
return 0;
}
时间复杂度:第一个for是n,第二个for代表n个(j-i)也就是n*(j-i),(j-i)大概可以估算为n/2,所以第二个for是 二分之n的平方(n^2/2) ,所以第三个for就是(n^2/2)个(j-i),此时由上可得这三个for的复杂度为 An的三次方(An^3) A为系数,可以不计,则为n^3。(具体推导方式参考《数据结构与算法分析—C语言描述》21页。
算法二:穷举—简
#include<stdio.h>
//求最大值序列和二
int main()
{
int sum,num;
int n,i,j,k;
scanf("%d",&n);//输入序列总数
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//输入序列
}
sum=0;//最大子序列和置0
for(i=0;i<n;i++)
{
num=0;//临时子序列和比较完归0
for(j=i;j<n;j++)//用二层for循环来遍历所有序列和的可能
{
num+=a[j];//求出所有序列和
if(num>sum)
{
sum=num;//比较得出最大值
}
}
}
printf("%d",sum);//输出最大值
return 0;
}
时间复杂度:,可以明显看出与算法一相比的区别,所以类比于算法一,n^2。
算法三—分而治之
#include<stdio.h>
//求最大子序列和三—分而治之
int max3(int a,int b,int c)
{
return ((a>b?a:b)>c)?(a>b?a:b):c;//用条件运算符来比较
}//求三个数的最大值
int maxsum(int a[],int left, int right)
{
int center,i;
int leftmaxsum,rightmaxsum;
int leftborder=0,rightborder=0;
int leftbordermax=0,rightbordermax=0;
if(left==right)
{
if(a[left]>=0)
{
return a[left];
}else{
return 0;
}
}//如果只有一个元素,正数不变,负数置零
center=(left+right)/2;//取中间序号
leftmaxsum=maxsum(a,left,center);//递归逐渐向左
rightmaxsum=maxsum(a,center+1,right);//递归逐渐向右
for(i=center;i>=left;i--)
{
leftborder+=a[i];
if(leftborder>leftbordermax)
{
leftbordermax=leftborder;
}
}//求出左边靠右的最大子序列和
for(i=center+1;i<=right;i++)
{
rightborder+=a[i];
if(rightborder>rightbordermax)
{
rightbordermax=rightborder;
}
}//求出右边靠左的最大子序列和
return max3(leftmaxsum,rightmaxsum,rightbordermax+leftbordermax);//调用max3函数
}//递归,层层深入。二分,步步为营。
int main()
{
int n,i;
scanf("%d",&n);//输入序列总数
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//输入序列
}
printf("%d",maxsum(a,0,n-1));//,调用maxsum函数,输出最大子序列和
return 0;
}
时间复杂度:NlnN(具体推导方式参考《数据结构与算法分析—C语言描述》24页。
算法四—联机算法
#include<stdio.h>
//求最大子序列和4,在线处理
int main()
{
int sum,num;
int n,i;
scanf("%d",&n);//输入序列总数
int a[n];
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);//输入序列
}
sum=num=0;//置0
for(i=0;i<n;i++)
{
num+=a[i];
if(num>sum)
{
sum=num;//及时存放
}else if(num<0)
{
num=0;//负则归0
}
}
return 0;
}
时间复杂度:N (◎﹏◎)