最大子段和
問題描述:
給定由n個整數(包含負整數)組成的序列a1,a2,...,an,求該序列子段和的最大值。
當所有整數均爲負值時定義其最大子段和爲0。
依此定義,所求的最優值爲:
例如,當(a1,a2 , a3 , a4 , a5 ,a6)=(-2,11,-4,13,-5,-2)時,
最大子段和爲:
11+(-4)+13 =20
解:
最大字段和:
一層循環:動態規劃,循環從0~n-1,代表最大子段和的字段的結束位置。使用temp作爲當前和的暫定值,
如果temp+a[i]<0則代表最大字段的開始位置可能從i開始,但也有可能不是,
當temp>sum的時候,做交換。
二層循環:第一層循環代表字段的開始位置,第二層循環代表字段的結束位置,temp標記依次加a[j]
當temp>sum時候,就交換,並且記住當前的i和j,作爲起始位置
三層循環:暴力尋找, 第一層循環代表字段的開始位置,第二層循環代表字段的結束位置,第三層循環做相應的加法
#include <stdio.h>
int n;
int a[100];
void first()
{//一層循環
int sum=0;
int temp=0;
for(int i=0;i<n;i++)
{
if(temp + a[i]<0){
temp=0;
}
else
temp+=a[i];
if(temp>sum){
sum=temp;
}
}
printf("%d\n",sum);
}
void second()
{//兩層循環
int sum=0;
int ii,jj;
for(int i=0;i<n;i++)
{
int temp=0;
for(int j=i;j<n;j++)
{
temp+=a[j];
if(temp>sum){
sum=temp;
ii=i;jj=j;
}
}
}
printf("%d->%d\n",ii,jj);
printf("%d\n",sum);
}
void third()
{//三層循環
int sum=0;
int ii,jj;
for(int i=0;i<n-1;i++)
{
for(int j=i;j<n;j++)
{
int temp=0;
for(int k=i;k<=j;k++)
{
temp+=a[k];
}
if(temp>sum){
sum=temp;
ii=i;jj=j;
}
}
}
printf("%d->%d\n",ii,jj);
printf("%d\n",sum);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("one:\n");
first();
printf("two:\n");
second();
printf("three:\n");
third();
return 0;
}