紫書第七章 暴力求解法(全排列演算法)

2021-08-15 04:16:14 字數 1536 閱讀 8713

/*

本程式是遞迴實現全排列演算法。

思想是分別讓誰打頭。以1,2,3,4為例,一共只有4位,

第一位可以分別讓1,2,3,4打頭,以第一位是1為例,

第二位可以分別讓2,3,4打頭,以第二位是2為例,

第三位可以分別讓3,4打頭,以第三位是4為例,

第四位固定是4,輸入此排列。

其他情況類似輸出。

去重:以序列1,2,2,3為例,一共四位,一共3個不同的數,

第一位可以讓1,2,3打頭,以第一位是1為例,

第二位可以讓2打頭,以第二位為2為例,

第三位的時候,由於前兩位中已經出現了2,和第三位相同,不能讓2第二次打頭,所以,

下面的演算法為了去除重複排列,沒有讓1與第三個2交換。

*/#include

#include

using

namespace

std;

//去重複函式

bool is_swap(int a,int st,int en)

return

true;

}//全排列演算法

void per(int a,int st,int en)}}

}int main()

; per(a,0,4);

return

0;}

#include

#include

using

namespace

std;

int main()

; sort(a,a+4);

do

參考劉汝佳《演算法競賽入門經典》(第2版)

以上面遞迴求全排列的演算法為例,下面的樹展示了遞迴的過程。

第0層:(,,,)

第1層:(1,,,)、(2,,,)、(3,,,)、(4,,,)

第2程:

上面1打頭的子結點是(1,2,,)、(1,3,,)、(1,4,,)

上面2打頭的子結點是(2,1,,)、(2,3,,)、(2,4,,)

上面3打頭的子結點是(3,1,,)、(3,2,,)、(3,4,,)

上面4打頭的子結點是(4,1,,)、(4,2,,)、(4,3,,)

把上面的畫成樹,就是解答樹。下面求一下解答樹的結點個數:

第一層:n

第二層:n*(n-1)

第三層:n*(n-1)*(n-2)

…… 第i層:n*(n-1)(n-2)…*(n-(i-1))=n!/(n-i)!

總的結點數是n!*(1/(n-1)!+1/(n-2)!+…+1/1!+1/0!),由泰勒展開式可知該式子趨向e*n!,則總結點數小於e*n!,又低第n層和第n-1層的結點數都是n!,最後兩層的結點數目佔據了2*n!,所以,多數情形下,解答樹上的借電腦幾乎全部**於最後一兩層。

參考劉汝佳《演算法競賽入門經典》(第2版):

如果某問題的解可以由多個步驟得到,而每個步驟都有若干種選擇(這時候選方案集可能會依賴於先前作出的選擇),且可以用遞迴列舉法實現,則它的工作方式可以用解答樹描述。

演算法競賽入門經典第七章暴力求解法7 1節第一題

演算法競賽入門經典 一書中的某題如下 輸入正整數n,按從小到大的順序輸出所有形如 abcde fghij n的表示式,其中a j恰好為數字0 9的乙個排列,2 n 79。樣例輸入 62樣例輸出 79546 01283 62 94736 01528 62 直接的解決方法就是對除數進行dfs暴力搜尋,直...

演算法學習筆記 13 暴力求解法01 列舉排列

所謂暴力求解法,大意應該是根據提議分析出的所有可能的情況 優化過的研究域 來一一研究,得到最終結果。第一節呢就是列舉排列。這裡的排列指的是乙個集合的元素中根據字典序進行排列。用wikioi的一道題來進行解釋吧 樣例輸入 sample input 3樣例輸出 sample output 1 2 3 1...

演算法競賽入門第七章 1 暴力列舉

def create m,obj list range 10 defremove 2 x,l l l l.remove x return l ans if m 0 return 0 for i in obj ans tmp create m 1,remove 2 i,obj for each in ...