問題描述:
給定有n個整數(可能為負整數)組成的序列,a1,a2,.......an,求該序列如
最優值為
max上述假定的意思也就是說最大欄位和(只有乙個字段)要麼為0,要麼大於0
int maxsum(int n,int *a,int &besti,int &bestj)
} //這樣下來就可以在i=1時找到其中的最大欄位和的值,下標i和j
return sum;
} //重複查詢,很明顯時間複雜度o(n^3)
仔細分析一下,第三個迴圈做了重複的工作,當j++後,thissum沒必要又從i...j計算一遍,只需要thissum+=a[j],便可將時間複雜度降低到o(n^2)
int maxsum(int n,int *a,int &besti,int &bestj)
} }return sum;
}
針對最大欄位和問題的解結構,它也適合分治法求解
。為什麼這麼說呢,因為分而治之的思想能夠降低該問題規模,同時該問題適合進行遞迴求解。
那麼如果按照n/2來劃分,那麼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[1:n/2],a[n/2+1:n]計算其最大欄位和s1,s2,然後相加s1+s2即為情形3的最優值,
int maxsubsum(int *a,int left,int right)
int s2=0;
int rights=0;
for(int j=center+1;j<=right;j++) //注意j這裡是從center+1
sum=s1+s2; //然後取其中最大值
if(sum
對於動態規劃法,得好好理解其思想,即何為動態規劃,我的理解是先從整體上找到規律,然後再自底向上求解,同時要注意這個底部即最小規模時問題的分析。
這裡我們先假設
既然b[j]表示我們所求的某個當前最大欄位和,那麼當b[j-1]>0時,b[j]=b[j-1]+a[j],否則,b[j]=a[j](因為b[j-1]都小於0了,如果a[j]>0這樣做只會拉低b[j],如果a[j]<0,摒棄b[j-1]只會對b[j]更有利,所以無論a[j]正負,只要b[j-1]<0,我就摒棄它,而只將a[j]作為b[j]的值;)
所以可得b[j]的動態規劃遞迴式:
int maxsum(int n,int *a)
return sum;
}
這是一維情形下的最大子段和,那麼二維下呢,比如說二維矩陣
常規思路時間複雜度o(m^2 n^2)
式中
設
先上**,該演算法時間複雜度o(m^2 n)
上圖是表示i=1,j=1..m,k=1...n的情況,一輪k下來,可得到i,j確定時,矩陣的最大子矩陣和,一輪j下來,可得到i確定時,矩陣的最大子矩陣和
那麼接下來看看,i=2時,如何得到最大子矩陣,這樣的一輪下來,便可得到整個矩陣的最大子矩陣和
最大子段和
設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...
最大子段和
問題表述 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,開頭的最大連續和,此時開頭已經確定了,那麼通過列舉...