最大子段和問題

最大子段和

問題描述:
給定由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;
} 


發佈了161 篇原創文章 · 獲贊 70 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章