轉載 - 整數劃分問題

出處: http://www.cnblogs.com/wanghetao/archive/2013/11/25/3442192.htmlhtml

整數劃分 --- 一個老生長談的問題:spa

描述

整數劃分是一個經典的問題。請寫一個程序,完成如下要求。.net

 

 

輸入
每組輸入是兩個整數n和k。(1 <= n <= 50, 1 <= k <= n)
輸出
對於輸入的 n,k;
第一行: 將n劃分紅若干正整數之和的劃分數。
第二行: 將n劃分紅k個正整數之和的劃分數。
第三行: 將n劃分紅最大數不超過k的劃分數。
第四行: 將n劃分紅若干個 奇正整數之和的劃分數。
第五行: 將n劃分紅若干不一樣整數之和的劃分數。
第六行: 打印一個空行
樣例輸入
5 2
樣例輸出
7
2
3
3
3
提示
樣例輸出提示:
1.將5劃分紅若干正整數之和的劃分爲: 5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
2.將5劃分紅2個正整數之和的劃分爲: 3+2, 4+1
3.將5劃分紅最大數不超過2的劃分爲: 1+1+1+1+1, 1+1+1+2, 1+2+2
4.將5劃分紅若干 奇正整數之和的劃分爲: 5, 1+1+3, 1+1+1+1+1
5.將5劃分紅若干不一樣整數之和的劃分爲: 5, 1+4, 2+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

         [2]  http://www.cnblogs.com/jackge/p/3163835.html

相關文章
相關標籤/搜索