設a=是n個整數的序列,稱為該序列的子串行,其中1<=i<=j<=n.子串行的元素之和稱為a的子段和.
例如,a=<-2,11,4,13,-5,-2>,那麼它的子段和是:
長度為1的子段和:-2,11,-4,13,-5,-2
長度為2的子段和:9,7,9,8,-7
長度為3的子段和:5,20,4,6
長度為4的子段和:18,15,2
長度為5的子段和:13,13
長度為6的子段和:11
其中最大的子段和是 11-4+13=20
1.蠻幹法:
列舉a的所有連續子串行並且求和,通過比較找出最大子串行.
演算法複雜度:o(n^3)
2.分治演算法:
在[n/2]將a分為a1和a2前後兩部分,
若分割點為k,即a[i...k],a[k+1...j]
取得連續最大值的情況有三種:
第一種情況:sum1 = a[i...k] 左部分的連續最大值
第二種情況:sum2 = a[k+1...j] 右部分的連續最大值
第三種情況:
該最大連續子串行一部分在左邊,一部分在右邊,這時
left = a[k]+a[k-1]+...+a[m] 從分割點向左最大連續子段和
right = a[k+1]+a[k+2]+...+a[n] 從分割點向右最大連續子段和
1<=m,n<=j
sum3 = left+right
取 max
遞推方程:
t(n) = 2t(n/2)+o(n), t(1) = 0
根據主定理演算法複雜度:
o(nlogn)
動態規劃演算法:
設c[i]為a[1...i]中必須包含元素a[i] 的最大子段和.
這樣,c[i]表示的是a的每一位並且必須加上這一位後的最大子段和.
遞推關係:
c[i] = max
從遞推式可以看出,當c[i-1]為負數時,直接取a[i]的值為c[i],這也是好理解的,
一定要清楚c[i]是包含當前a[i]的最大連續子串行的和
演算法複雜度:
o(n)
演算法:
package com.動態規劃;
/// /// 求解最大子段和,返回結果以及最優解的始末下標
///
/// 輸入序列
/// 返回最優解的起始下標
/// 返回最優解的結束下標
/// 最大子段和
public class maxsubsum
int beginindex =0,endindex = 0;
int cursum = seq[0] ;
int bestresult = seq[0];
int curbeginindex = 0;
for(int i=1; i0)else
//每對乙個數進行處理後都要比較更新最大值
if(cursum > bestresult)
} system.out.println("開始的下標:"+beginindex+" 結束的下標:"+endindex);
return bestresult; }
public static void main(string args) ;
//int seq = ;
for(int i:seq)
system.out.println();
int result = maxsubsum(seq);
system.out.println("最大子串行的和為:"+result);
}}
結果:
20 -11 10 -1 -4 -5 -10 -2 -1 -2 -1 -9 11
開始的下標:0 結束的下標:0
最大子串行的和為:20
最大子段和
問題表述 n個數 可能是負數 組成的序列a1,a2,an.求該序列 例如 序列 2,11,4,13,5,2 最大子段和 11 4 13 20。1 窮舉演算法 o n3 o n2 2 分治法 將序列a 1 n 從n 2處截成兩段 a 1 n 2 a n 2 1 n 例項 三 最大子段和 問題表述 n個...
最大子段和
再給頂的n個數的陣列中選出連續的若干個數,使得他們的和是最大的,即最大連續自序列和.列如.序列.1 2 3 1 6 5 9 結果 當取子串行 3,1,6,5,9 結果12 我的思路.1.最大連續子串行的開頭是在1.n之中.的最大連續和 2.求出以i,開頭的最大連續和,此時開頭已經確定了,那麼通過列舉...
最大子段和
問題描述 給定有n個整數 可能為負整數 組成的序列,a1,a2,an,求該序列如 最優值為 max上述假定的意思也就是說最大欄位和 只有乙個字段 要麼為0,要麼大於0 int maxsum int n,int a,int besti,int bestj 這樣下來就可以在i 1時找到其中的最大欄位和的...