最大子段和是指在一串有正负整数的数中找到和最大的子段。最大子段的解法有三种,穷举法O(n^3)/O(n^2),分治法,动态规划法O(n)如下。在最大子段和问题中要解决最大子段和的值和最大子段两个关键点。
这里以
ACM-最大子段和升级版
为例进行记录。
函数 slove
用于填当前最大子段和值数组b[]并且记下最大子段的起始位置begin、end。求出end后递减,子段和减到0之后,记下当前的指针即为begin。
void solve(){
end=0;
begin=0;
b[0]=a[0];
maxSum=b[0];
for (int i = 1; i < n; i++)
{
if(b[i-1]>0)
b[i]=b[i-1]+a[i];
else
b[i]=a[i];
if(b[i]>maxSum){
maxSum=b[i];
end=i;
}
int maxSum2= maxSum;
for(int i=end;i>=0;i--){
maxSum2=maxSum2-a[i];
if(maxSum2==0)
begin=i;
}
}
}
完整AC代码如下
#include<stdio.h>
#include<math.h>
#include<string.h>
int a[100],b[100];
int n,maxSum,end,begin;
void solve(){
end=0;
begin=0;
b[0]=a[0];
maxSum=b[0];
for (int i = 1; i < n; i++)
{
if(b[i-1]>0)
b[i]=b[i-1]+a[i];
else
b[i]=a[i];
if(b[i]>maxSum){
maxSum=b[i];
end=i;
}
int maxSum2= maxSum;
for(int i=end;i>=0;i--){
maxSum2=maxSum2-a[i];
if(maxSum2==0)
begin=i;
}
}
}
int main(void){
while (scanf("%d",&n)!=EOF)
{
for (int i = 0; i <n; i++)
{
scanf("%d",&a[i]);
}
solve();
printf("%d %d %d\n",maxSum,begin+1,end+1);
}
return 0;
}
版权声明:本文为n3232原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。