【问题描述】
给定n 个整数(可以为负数)的序列<a1, a2, … , an>,求:
【输入形式】输入整数个数n,整数序列
【输出形式】最大字段和及相应子序列
【样例输入】
6
-2 11 -4 13 -5 -2
【样例输出】
20
11 -4 13
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int MaxSubSum_Violent(int *a,int n,int& besti,int& bestj)
{
int sum=0;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
int thissum=0;
for(int k=i; k<=j; k++)
{
thissum+=a[k];
}
if(thissum>sum)
{
sum=thissum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int MaxSubSum_Optimized(int *a,int n,int &besti,int &bestj)
{
int sum=0;
for(int i=0; i<n; i++)
{
int thissum=0;
for(int j=i; j<n; j++)
{
thissum+=a[j];
if(thissum>sum)
{
sum=thissum;
besti=i;
bestj=j;
}
}
}
return sum;
}
int CrossSubArray(int *a,int left,int mid,int right)
{
int leftsumMax=0,rightsumMax=0,temp=0;;
for(int i=mid; i>=left; i--)
{
temp+=a[i];
if(temp>=leftsumMax)
{
leftsumMax=temp;
}
}
temp=0;
for(int j=mid+1; j<=right; j++)
{
temp+=a[j];
if(temp>=rightsumMax)
{
rightsumMax=temp;
}
}
int crosssum=leftsumMax+rightsumMax;
return crosssum;
}
int MaxSubSum_DivideConquer(int *a,int left,int right)
{
int sum=0;
if(left==right)
{
sum=a[left];
}
else
{
int mid=(left+right)/2;
int leftsum=MaxSubSum_DivideConquer(a,left,mid);
int rightsum=MaxSubSum_DivideConquer(a,mid+1,right);
int crosssum=CrossSubArray(a,left,mid,right);
if(leftsum>=rightsum&&leftsum>=crosssum)
{
sum=leftsum;
}
else if(rightsum>=leftsum&&rightsum>=crosssum)
{
sum=rightsum;
}
else if(crosssum>=rightsum&&crosssum>=leftsum)
{
sum=crosssum;
}
}
return sum;
}
int MaxSubSum_DynamicProgram(int *a,int n)
{
int Max_sum=0;
int *f=(int *)malloc(sizeof(int)*(n+1));
for(int i=0; i<n; i++)
{
f[i]=a[i];
}
for(int i=1; i<=n; i++)
{
if(f[i-1]+a[i]>=a[i]) f[i]=f[i-1]+a[i];
if(f[i-1]+a[i]<a[i]) f[i]=a[i];
if(f[i]>=Max_sum) Max_sum=f[i];
}
return Max_sum;
}
int main()
{
int n=0;
scanf("%d",&n);
int *a=(int*)malloc(sizeof(int)*(n+1));
if(!a) exit(-2);
for(int i=0; i<n; i++)
{
scanf("%d",a+i);
}
int besti,bestj;
printf("%d\n",MaxSubSum_Violent(a,n,besti,bestj));
for(int i=besti; i<=bestj; i++)
{
printf("%d ",a[i]);
}
}