算法1:穷举法,对所有的(i,j)对,顺序求和a[i]+…a[j]并比较出较大的和
算法2:分治法,将数组分成左右两半,分别计算左边的最大和、右边的最大和、跨边界的最大和,然后比较其中的最大者。
算法3:动态规划法
#include<stdio.h>
#include<string.h>
//穷举法求出所有子段和的情况,比较得到较大值 O(n^3)
void Sum(int *arr,int len)
{
int sumNum=0;
int maxNum=-100000;
for(int i=0;i<len;i++)
{
for(int j=i;j<len;j++)
{
sumNum=0;
for(int k=i;k<=j;k++)
{
sumNum+=arr[k];
}
if(sumNum>maxNum)
{
maxNum=sumNum;
}
}
}
printf("%d\n",maxNum);
}
//对穷举法进行的改进 O(n^2)
void Sum1(int *arr,int len)
{
int sumNum=0;
int maxNum=-100000;
for(int i=0;i<len;i++)
{
sumNum=0;
for(int j=i;j<len;j++)
{
sumNum+=arr[j];
if(sumNum>maxNum)
{
maxNum=sumNum;
}
}
}
printf("%d\n",maxNum);
}
int main()
{
int a=0;
scanf("%d",&a);
int arr[a]={0};
for(int i=0;i<a;i++)
{
scanf("%d",&arr[i]);
}
int len=sizeof(arr)/sizeof(arr[0]);
Sum(arr,len);
}
结果显示如下:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<iostream>
using namespace std;
//使用动态规划求解最大子段和 O(n)
//dp[i]表示以arr[i]结尾的最大子段和,dp[i]=max(dp[i-1]+arr[i],arr[i])
void MaxSum(int *arr,int len)
{
int max=-10000;
int dp[len]={0};
dp[0]=arr[0];
for(int i=1;i<len;i++)
{
if(dp[i-1]>=0)
{
dp[i]=dp[i-1]+arr[i];
}
else
{
dp[i]=arr[i];
}
if(max<=dp[i])
{
max=dp[i];
}
}
printf("%d\n",max);
}
//对动态规划做出的改进,省略了dp[]数组,只需要两个临时变量
// void MaxSum(int *arr,int len)
// {
// int max=-10000;
// int temp=0;
// temp=arr[0];
// for(int i=1;i<len;i++)
// {
// if(temp>=0)
// {
// temp=temp+arr[i];
// }
// else
// {
// temp=arr[i];
// }
// if(max<=temp)
// {
// max=temp;
// }
// }
// printf("%d\n",max);
// }
int main()
{
int n=0;
scanf("%d",&n);
int arr[n]={0};
for(int i=0;i<n;i++)
{
scanf("%d",&arr[i]);
}
int size=sizeof(arr)/sizeof(arr[0]);
MaxSum(arr,size);
}