問題:將給定正整數n表示成一系列正整數之和n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。求正整數n的不同劃分個數p(n)。
有些問題本身都具有比較明顯的遞迴關係,因而容易用遞迴函式直接求解。而有些問題遞迴關係卻不明顯。
在本例中,如果設p(n)為正整數n的劃分數,則難以找到遞迴關係,因此考慮增加乙個自變數:將最大加數不大於m的劃分個數記作q(n,m)。可以建立q(n,m)的如下遞迴關係:
n = 1 或者m =1,這種情況下,可能的劃分只有一種,為最小的子問題。
m >= n > 1,由於m不可能大於n,因此此時m就是n,此時一定存在乙個劃分就是n本身,去掉這個劃分的話,就還有q(n,n-1)種劃分。
1 < m < n,這種情形是最重要的。q(n,m) = q(n,m-1) + 最大加數是m的所有劃分,問題的最後部分也是關鍵就是求出最大加數是m的所有劃分。與之前的思路相似,最大加數是m的所有劃分中,一定都含有乙個m,那麼去掉這個m,就可以寫成q(n-m,m),遞推式就完成了。
分治不需要證明,此遞推應該會收斂到最小子問題,但是有重複計算。
//生成正整數n的劃分個數
//輸入:乙個正整數n
//輸出:劃分個數
int q(int n,int m){
if(n==1 || m==1) return 1;
if(m>=n) return 1+q(n,n-1);
if(m關於這種複雜度計算仍然存疑,因為其複雜度的遞推過程不明確,難以確定遞推樹。
注意在建立遞迴關係時,一定要注意考察是否覆蓋了所有情況,例如本題中m=1&&n=1和m=1||n=1的區別。
注意遞推關係是否收斂,即子問題是否可以合併成原問題。
分治可以借助中間變數盤活全域性。
整數劃分 分治法
整數劃分經典演算法了,不做解釋,自己做了一下,鍛鍊遞迴能力!1 include 2 3int bufferarray 1000 快取陣列 4int bufferlenth 0 快取陣列的當前長度 5int outputsignal 1 當前輸出的控制訊號 6int total 0 劃分的總數 78 ...
分治法 全排列 整數劃分 最近點對問題 棋盤覆蓋
一 分治法的求解過程 1 劃分 既然是分治,當然需要把規模為 n的原問題劃分為 k個規模較小的子問題,並盡量使這 k個子問題的規模大致相同。2 求解子問題 各子問題的解法與原問題的解法通常是相同的,可以用遞迴的方法求解各個子問題,有時遞迴處理也可以用迴圈來實現。3 合併 把各個子問題的解合併起來,合...
分治法求解大整數相乘問題
問題描述 設x和y都是n位的大整數,現在要計算它們的乘積xy。提示 採用分治法求解兩個十進位製大整數的乘法,以提高乘法的效率,減少乘法次數。計算公式為 xy ac10n a b d c ac bd 10n 2 bd 下面的例子演示了分治演算法的計算過程。設x 314l,y 5327,用上述演算法計算...