題目
將乙個正整數n表示成一系列正整數之和,n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥ 1,k ≥1
正整數n的乙個這種表示稱為正整數n的乙個劃分。正整數n的不同劃分個數稱為正整數n的劃分數,記做p(n)。
如正整數6有如下11種不同的劃分,所以p(6)=11。
6;5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1,
1+1+1+1+1+1;
我先檢討一下我們問題吧,剛看到這個題,感覺挺簡單的,以至於題目中要求乙個劃分必須是乙個非增序列我都沒看到,其次呢,對於這個題,我感覺遞迴出口應該是當n=1時,返回1就可以了,遞迴函式呢,比如求p(6)的話,應該是在p(5)的基礎上加一些個條件啥的,顯然,最後一定不對。
接下來看這道題,我覺得這種思維挺難的,難在哪兒呢?這道題將p(n)進行了乙個轉化,轉化為乙個q(n,m),轉化後的這個式子的意思是:對正整數n進行乙個劃分,劃分中的最大數值不超過m,舉個例子,q(6,4),表示為對6進行劃分,最大數值不能超過4,這個m具體啥含義呢?我們看題目,劃分序列要求是乙個非增的序列,那麼,n1在一般情況下是不是可以理解為整個序列的最大值呢?我覺得是可以的,以上我感覺就是最難的部分,特別是公式轉化那一塊。
有個q(n,m)這個公式,我們繼續分析,由易到難,首先我要說的是,假如要求p(6),實則求q(6,6),這個應該沒問題吧?對6的劃分,不就是對6的劃分中,最大值只能是6麼?,題目規定ni不能是0或者負數。
第二點:q(n,m),當m>n時,它其實等價於q(n,n),舉個例子,q(4,6),求4的劃分,最大值不能超過6,題目規定,題目規定ni不能是0或者負數,其實在這,我們可以多想一下,與其說劃分序列的各項ki不大於m,一般情況下,這不主要就是對k1而言麼?
第三點:舉一般的例子來說,q(n,m),它其實包含兩種情況,乙個種,k1等於m,第二種k1不等於m,轉化一下,即k1
<=m-1,這兩種情況得多想想,懂了之後我們繼續,對於第一種情況,當k1等於m時,我們會得到這樣乙個十字,n=m+k2+k3+…kn,移項後得到n-m=k2+k3+…kn,有沒有感覺像是乙個遞迴式?q(n-m,m);第二種情況:k1不等於m,即k1
<=m-1,那麼他是不是就等於q(n,m-1);綜上,我們可以得到q(n,m)=q(n-m,m)+q(n,m-1);
第四點:上面的第二點主要說的是m>n的情況,第三點主要說的是一般情況下的m#include
using
namespace std;
//m為n劃分的子樹中最大的整數
intrecursion
(int n,
int m)
intmain
(int argc,
char
** ar**)
整數劃分問題遞迴
整數劃分問題是演算法中的乙個經典命題之一,有關這個問題的講述在講解到遞迴時基本都將涉及。所謂整數劃分,是指把乙個正整數n寫成如下形式 n m1 m2 mi 其中mi為正整數,並且1 mi n 則為n的乙個劃分。如果中的最大值不超過m,即max m1,m2,mi m,則稱它屬於n的乙個m劃分。這裡我們...
整數劃分問題 遞迴
1.程式直接或間接呼叫自身的程式設計技巧稱為遞迴演算法 recursion 2.乙個過程或函式在其定義或說明中又直接或間接呼叫自身的一種方法,它通常把乙個大型複雜的問題層層轉化為乙個與原問題相似的規模較小的問題來求解,遞迴策略只需少量的程式就可描述出解題過程所需要的多次重複計算,大大地減少了程式的 ...
整數劃分問題(遞迴)
將正整數 n 表示成一系列正整數之和,n n1 n2 nk,其中 n1 n2 nk 1 k 1 正整數 n 的這種表示稱為正整數 n 的劃分。正整數 n 的不同的劃分個數稱為正整數 n 的劃分數,記作 p n 例如正整數 6 有如下 11 種不同的劃分,所以 p 6 11 6 5 1 4 2,4 1...