組合演算法的程式實現及分析比較

2021-04-01 02:15:38 字數 1185 閱讀 2683

【問題】    組合問題

問題描述:找出從自然數1、2、... 、n中任取r個數的所有組合。例如n=5,r=3的所有組合為:

1,2,3

1,2,4

1,3,4

2,3,4

1,2,5

1,3,5

2,3,5

1,4,5

2,4,5

3,4,5

用程式實現有幾種方法:

1)窮舉法,程式如下

【程式】

#include

const int n=5,r=3;

int  i,j,k,counts=0;

int main()

printf("%d",counts);

return 0;

}但是這個程式都有乙個問題,當r變化時,迴圈重數改變,這就影響了這一問題的解,即沒有一般性。

2)遞迴法

分析所列的10個組合,可以採用這樣的遞迴思想來考慮求組合函式的演算法。

設函式為void  ***b(int m,int k)為找出從自然數1、2、... 、m中任取k個數的所有組

合。當組合的第乙個數字選定時,其後的數字是從餘下的m-1個數中取k-1數的組合。這

就將求m個數中取k個數的組合問題轉化成求m-1個數中取k-1個數的組合問題。設函式引

入工作陣列a[ ]存放求出的組合的數字,約定函式將確定的k個數字組合的第乙個數字放

在a[k]中,當乙個組合求出後,才將a[ ]中的乙個組合輸出。第乙個數可以是m、m-1、

...、k,函式將確定組合的第乙個數字放入陣列後,有兩種可能的選擇,因還未去頂組

合的其餘元素,繼續遞迴去確定;或因已確定了組合的全部元素,輸出這個組合。細節

見以下程式中的函式***b。

【程式】

#include

#include

using namespace std;

# define    maxn    100

int a[maxn];

int counts=0;

void printtime(void) //列印當前時間的函式 }}

int main()

同上面的遞迴的程式進行比較,同樣用g++ o2優化。當n=40,r=11,遮蔽掉輸出,得到的結果都是2311801440項,遞迴程式用了23至24秒,回溯用了19至20秒。

組合演算法實現

組合 乙個集的元素的組合是乙個子集。s的乙個k 組合是s的乙個有k個元素的子集。組合具有無序性。若兩個子集的元素完全相同僅順序不同,看作同乙個組合。組合符號 這裡介紹4中常見的組合形式 1.完全組合。2.不重複完全組合。3.選擇組合。4.有重複選擇組合。1.完全組合 從n元素集s中取出所有的k個元素...

銀幣組合演算法分析

題目 有足夠量的2分 5分 1分硬幣,請問湊齊1元錢有多少種方法?此題乍看上去,只會覺得完全無法入手,但是按照由簡至繁的思路,我們可以先考慮極端簡單的情況,假如把問題規模縮小成 有足夠量的1分硬幣,請問湊齊1分錢有多少種方法?毫無疑問,答案是1。得到這一答案之後,我們可以略微擴大問題的規模 有足夠量...

組合演算法 遞迴實現

假設在n個數中選取m 0 從n個數中選取編號最大的數,然後在剩下的n 1個數裡面選取m 1個數,直到從n m 1 個數中選取1個數。從n個數中選取編號更小的乙個數,繼續執行第一步,直到當前可選編號最大的值為m。下面是遞迴方法的實現 求從陣列a 1.n 中任選m個元素的所有組合。a 1.n 表示候選集...