整數劃分問題即給定乙個正整數n,將該數表示為一系列正整數之和,
n=n1+n2+n3+n4+…+nk (n1>=n2>=n3>=n4…>=nk>=1,k>=1)
正整數n的這種表示成為正整數n的劃分。正整數n的不同劃分個數成為正整數n的劃分數,記作p(n)。
例如,正整數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可以分解出的最大加數值為m,則先將n表示成m+(n-m),接下來可對n-m再次進行遞迴呼叫,並將分解出的加數記錄再len陣列中,長度表示成result,考慮到在n和m進行不斷變化以後,m和n的值又以下不同的情況,進行以下分析
** 所以m>n時q(n,m)=q(n,n)** 當n當n=0或者m=0時都不可再分,此時該式分解完畢,可以直接輸出表示式
當m=1而n>0時,m不可以再進行分解,而只能將n表示成多個值為1的加數相加,在len中記錄下m的值並遞迴呼叫
q(n-1,m,result+1,len);
當m=n的時,此時加數為m可以作為乙個表示式,在len中記錄下m的值,並輸出該表示式,同時可將m再次分解為更小的數,遞迴呼叫q(n,m-1,result,len)+1,此處加一用以統計表示式的個數在取加數為m時算一項。
而除了以上幾種情況,就只剩下n>m的情況,此時可以直接成兩種情況,一種情況是最大值為m,此時記錄下m,並對剩下的n-m繼續進行分解,同時,還可以將加數分解為比m小的值,所得表示式的個數為兩個表示式個數之和,遞迴呼叫
q(n-m,m,result+1,len)+q(n,m-1,result,len);
(在遞迴n-m時result加一是因為要記錄下當前加數為m的情況,此時剩下的要進行分解的只有n-m這一部)
具體**如下
#include
using
namespace std;
void
prin
(int len,
int result)
//這裡要注意result不要直接加,而是加1放在遞迴呼叫中
intq
(int n,
int m,
int result,
int len)
return1;
//當m等於1時只有一種方法了,所以返回1
}else
if(m>n)
return
q(n,n,result,len)
;//當n=m時輸出並往下劃分
else
if(m==n)
// 當n>m時直接進行劃分
else
}int
main()
;int result=0;
cout<"共可以分解出"
<<
q(n,n,result,len)
<<
"個表示式"
<}}
表示式樹的建立與輸出
表示式樹的建立與輸出 編乙個程式,讀入先序遍歷字串,根據此字串建立一棵二叉樹 以指標方式儲存 請注意的是,我們保證該樹一定是表示式樹 見教材5.2 5.8 例如下面的先序遍歷字串 建立起此二叉樹以後,再按要求輸出二叉樹。輸入輸入由多組測試資料組成。每組資料報含一行字串,即表示式樹的先序遍歷序列,字串...
表示式樹的建立與輸出
題目描述 編乙個程式,讀入先序遍歷字串,根據此字串建立一棵二叉樹 以指標方式儲存 請注意的是,我們保證該樹一定是表示式樹 見教材5.2 5.8 例如下面的先序遍歷字串 每組資料報含一行字串,即表示式樹的先序遍歷序列,字串長度大於0且不超過100。輸出對於每組資料,輸出一行,內容是該表示式樹的全括號表...
表示式樹的建立與輸出
表示式樹的建立與輸出編乙個程式,讀入先序遍歷字串,根據此字串建立一棵二叉樹 以指標方式儲存 請注意的是,我們保證該樹一定是表示式樹 見教材5.2 5.8 例如下面的先序遍歷字串 13 5 9 運算子只可能是加減乘除,數值為小於等於100,各結點用空格分開,其中 代表空樹。建立起此二叉樹以後,再按要求...