最大子段和詳解

來源:互聯網
上載者:User

 

問題的提出:

給定n個整數(可能為負數)組成的序列a[1],a[2],a[3],…,a[n],求該序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。當所給的整均為負數時定義子段和為0,依此定義,所求的最優值為

Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n

 例如,當(a1,a2,a3,a4,a4,a6)=(-2,11,-4,13,-5,-2)時,最大子段和為20

方法一:

蠻力法

方法二:

分治法

演算法描述如下:

 

針對最大子段和這個具體問題本身的結構,我們還可以從演算法設計的策略上對上述O(n^2)計算時間演算法進行更進一步的改進。從問題的解結構也可以看出,它適合於用分治法求解。

如果將所給的序列a[1:n]分為長度相等的兩段a[1:n/2]和a[n/2+1:n],分別求出這兩段的最大子段和,則a[1:n]的最大子段和有三種情況:

(1) a[1:n]的最大子段和與a[1:n/2]的最大子段和相同

(2) a[1:n]的最大子段和與a[n/2+1:n]的最大子段和相同

(3) a[1:n]的最大子段和為a[i]+…+a[j],並且1<=i<=n/2,n/2+1<=j<=n。

對於(1)和(2)兩種情況可遞迴求得,但是對於情況(3),容易看出a[n/2],a[n/2+1]在最大子段中。因此,我們可以在a[1:n/2]中計算出s1=max(a[n/2]+a[n/2-1]+…+a[i]),0<=i<=n/2,並在a[n/2+1:n]中計算出s2= max(a[n/2+1]+a[n/2+2]+…+a[i]),n/2+1<=i<=n。則s1+s2為出現情況(3)的最大子段和。據此可以設計出最大子段和問題的分治演算法如下:

代碼如下:

#include<stdio.h><br />#define MAX 100<br />int maxsub(int left,int right);<br />int a[MAX];<br />int main()<br />{<br />int i;<br />int count;<br />scanf("%d",&count);<br />for(i=0;i<count;i++)<br />{<br />scanf("%d",&a[i]);<br />}<br />printf("%d/n",maxsub(0,count-1));<br />return 0;<br />}<br />int maxsub(int left,int right)<br />{<br />int center,i;<br />int sum,left_sum,right_sum;<br />int left_max,right_max;<br />center=(left+right)/2;<br />if(left==right)<br />return a[left];<br />else<br />{<br />left_sum=maxsub(left,center);<br />right_sum=maxsub(center+1,right);<br />sum=0;<br />left_max=0;<br />for(i=center;i>=left;i--)<br />{<br />sum+=a[i];<br />if(sum>left_max)<br />left_max=sum;<br />}<br />sum=0;<br />right_max=0;<br />for(i=center+1;i<=right;i++)<br />{<br />sum+=a[i];<br />if(sum>right_max)<br />right_max=sum;<br />}<br />sum=right_max+left_max;<br />if(sum<left_sum)<br />sum=left_sum;<br />if(sum<right_sum)<br />sum=right_sum;<br />}<br />return sum;<br />} 

 

方法三:

動態規劃法

演算法描述如下:

 

在對於上述分治演算法的分析中我們注意到,若記b[j]=max(a[i]+a[i+1]+..+a[j]),其中1<=i<=j,並且1<=j<=n。則所求的最大子段和為max b[j],1<=j<=n。

由b[j]的定義可易知,當b[j-1]>0時b[j]=b[j-1]+a[j],否則b[j]=a[j]。故b[j]的動態規劃遞迴式為:

b[j]=max(b[j-1]+a[j],a[j]),1<=j<=n。

代碼如下:

#include<stdio.h><br />int main()<br />{<br />int count;<br />int a[100];<br />int b[100];<br />int i;<br />int max;<br />scanf("%d",&count);<br />for(i=0;i<count;i++)<br />{<br />scanf("%d",&a[i]);<br />}<br />b[0]=a[0];<br />max=b[0];<br />for(i=1;i<count;i++)<br />{<br />if(b[i-1]>0)<br />b[i]=b[i-1]+a[i];<br />else<br />b[i]=a[i];<br />if(b[i]>max)<br />max=b[i];<br />}<br />printf("%d/n",max);<br />return 0;<br />} 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.