整數劃分問題及其算法

整數劃分問題及其算法

一、問題描述

整數劃分問題是將一個正整數n拆成一組數連加並等於n的形式,且這組數中的最大加數不大於n
  
如整數的6劃分爲:
  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
11種。

二、算法描述

下面通過遞歸方法得到一個正整數的劃分數。
 
遞歸函數的聲明爲 int split(int n, int m);其中n爲要劃分的正整數,m是劃分中的最大加數(m > n時,最大加數爲n)


 Ⅰ.
n = 1m = 1時,split的值爲1,可根據上例看出,只有一個劃分1 1 + 1 + 1 + 1 + 1 + 1
 
可用程序表示爲if(n == 1 || m == 1) return 1;

 

.下面看一看m n的關係。它們有三種關係
 (1) m > n

在整數劃分中實際上最大加數不能大於n,因此在這種情況可以等價爲split(n, n);
 
可用程序表示爲if(m > n) return split(n, n);
   
 (2) m = n
 
這種情況可用遞歸表示爲split(n, m - 1) + 1,從以上例子中可以看出,就是最大加數爲6和小於6的劃分之和

 
可用程序表示爲if(m == n) return (split(n, m - 1) + 1);
 (3) m < n
 
這是最一般的情況,在劃分的大多數時都是這種情況。從上例可以看出,設m = 4,那split(6, 4)的值是最大加數小於4劃分數和整數2的劃分數的和。
 
可用程序表示爲split(n, m - 1) + split(n - m, m)

三、程序語言實現

  因爲算法是程序的核心部分,而算法是一致的,所以下面的程序思路一致,大同小異,只是形式不一而已。

1.Java實現:

 

2.C++實現:

 
C++實現的比較潦草,沒有讓用戶輸入數據,沒有一般交互性,不過可以自己再改正一下!

 

 

就遞歸方式而言,最大的不好之處就是遞歸次數太多,做了太多的冗餘計算。
(N,M)         
所需時間(ms    
100,100        250
120,120         1281.3
140,140         6297
160,160         27484.7
180,180         110844.5
200,200         398417.4
相對而言,動態規劃效率要高很多,不是一個數量級的,篇在介紹啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章