出處: http://www.cnblogs.com/wanghetao/archive/2013/11/25/3442192.htmlhtml
整數劃分 --- 一個老生長談的問題:spa
整數劃分是一個經典的問題。請寫一個程序,完成如下要求。.net
5 2
7 2 3 3 3
下面是我根據網上的資料, 寫出本身的分析和實現過程.htm
分析:blog
本題使用動態規劃(Dynamic Programming)方法解決get
一 求將n劃分爲若干正整數之和的劃分數class
1. 若劃分的多個整數能夠相同程序
設dp[i][j]爲將i劃分爲不大於j的劃分數方法
(1) 當i<j 時,i不能劃分爲大於i的數,因此dp[i][j]=dp[i][i];di
(2) 當i>j 時,能夠根據劃分中是否含有j分爲兩種狀況。若劃分中含有j,劃分方案數爲dp[i-j][j];若劃分數中不含j,至關於將i劃分爲不大於j-1的劃分數,爲dp[i][j-1]。因此當i>j時dp[i][j]=dp[i-j][j]+dp[i][j-1];
(3) 當i=j 時,若劃分中含有j只有一種狀況,若劃分中不含j至關於將i劃分爲不大於j-1的劃分數。此時dp[i][j]=1+dp[i][j-1]。
dp[n][n]能夠解決問題1,dp[n][k]表示將n劃分爲最大數不超過k的劃分數,能夠解決問題3。
2. 若劃分的正整數必須不一樣
設dp[i][j]爲將i劃分爲不超過j的不一樣整數的劃分數
(1) 當i<j時,i不能劃分爲大於i的數,因此dp[i][j]=dp[i][i];
(2) 當i>j時,能夠根據劃分中是否含有j分爲兩種狀況。若劃分中含有j,則其他的劃分中最大隻能是j-1,方案數爲dp[i-j][j-1];若劃分中不含j,至關於將i劃分爲不大於j-1的劃分數,爲dp[i][j-1]。因此當i>j時dp[i][j]=dp[i-j][j-1]+dp[i][j-1];
(3) 當i=j時,若劃分中含有j只有一種狀況,若劃分中不含j至關於將i劃分爲不大於j-1的劃分數。此時dp[i][j]=1+dp[i][j-1]
dp[n][n]表示將n劃分爲不一樣整數的劃分數,能夠解決問題5.
二 將n劃分爲k個整數的劃分數
設dp[i][j]爲將i劃分爲j個整數的劃分數。
(1) i<j爲不可能出現的狀況,dp[i][j]=0;
(2) 若i=j,有一種狀況:i能夠劃分爲i個1之和,dp[i][j]=1;
(3) 若i>j,能夠根據劃分數中是否含有1分爲兩類:若劃分數中含有1,能夠使用「截邊法」將j個劃分分別截去一個1,把問題轉化爲i-j的j-1個劃分數,爲dp[i-j][j-1]; 若劃分中不包含1,使用「截邊法」將j個劃分數的最下面一個數截去,將爲題轉化爲求i-j的j個劃分數,爲dp[i-j][j]。因此i>j時dp[i][j]=dp[i-j][j-1]+dp[i-j][j]。
dp[n][k]爲將n劃分爲k個整數的劃分數,可解決問題2。
三 將n劃分爲若干正奇數之和的劃分數
設f[i][j]爲將i劃分爲j個奇數之和的劃分數,g[i][j]爲將i劃分爲j個偶數之和的劃分數。
使用截邊法,將g[i][j]的j個劃分都去掉1,能夠獲得f[i-j][j],因此
g[i][j] = f[i-j][j]。
f[i][j]中有包含1的劃分方案和不包含1的劃分方案。對於包含1的劃分方案,能夠將1的劃分除去,轉化爲「將i-1劃分爲j-1個奇數之和的劃分數」,即f[i-1][j-1];對於不包含1的劃分方案,能夠使用截邊法對j個劃分每個都去掉一個1,轉化爲「將i-j劃分爲j個偶數之和的劃分數」,即g[i-j][j]。
因此f[i][j]=f[i-1][j-1]+g[i-j][j]。
f[n][0]+f[n][1]+……+f[n][n]爲將n劃分爲若干奇數的劃分數,爲問題4的答案。
參考: [1] http://blog.csdn.net/a83610312/article/details/12685653