全排列,迴圈,交換,遞迴,回溯

2021-10-13 18:23:25 字數 1092 閱讀 2519

舉例

eg: 的全排列是多少?
利用高中全排列的知識,做出如下解釋:第乙個位置可放3個元素,第二個位置還剩下2個元素可放,最後放乙個元素,得到3 * 2 * 1 = 6 種放法。

那麼如何用**表示上面的放法呢?

第乙個位置三種放法,首先怎麼得到三個資料呢?

第一次遍歷,自己和自己交換,第二次遍歷,自己和第二個數交換,第三次,自己和第三個數交換。

int k =0;

int m =2;

for(

int i = k; i <= m; i++

)/* 這裡我們看到要想第一次得到自己,第二次得到第二個數,

第三次得到第三個數的前提是,每一次交換必須保證是的初始態,

下面解釋怎麼復原*/

那麼第二個位置兩種方法怎麼來表示呢,和第乙個位置一樣一定也是迴圈,聰明的小夥伴一定發現了,下標起始位置不同。問題又來了,第乙個位置進行了第一次交換後第二個位置怎麼進行第一次交換?

遞迴鴨!

perm

(list, k +

1, m)

那麼每次怎麼進行復原,比如,下乙個全排列是多少,下乙個狀態一定是,首先我們得還原為,怎麼還原?第三次迴圈結束條件不滿足,不進入迴圈體,返回上一級,我們剛剛怎麼交換的就怎麼交換回來,再swap()一下。這就是回溯的體現。
swap

(list[k]

,list[i]

);

那麼到這裡,我們其實已經得到**的核心部分,剩下的部分就是出口問題,我們想想,最後乙個數用不用交換???是不是不用,倒數第二個數的交換,是不是就已經完成了,所以出口就是倒數第二個數完成後,準備進入下一次交換時,遞迴返回。

**如下:

template 

void

perm

(type list,

int k,

int m)

cout << endl;

}else}}

intmain()

;perm

(list,0,

2);return0;

}

用腦子跑一下:

使用with遞迴回溯

向上回溯,查詢頂級部門 declare pdeptid uniqueidentifier with dept deptid,pdeptid as select udepid,uparentid from oa.dbo.depinfo where udepid in select p.udepid f...

遞迴回溯總結

遞迴回溯法對解空間樹作深度優先搜尋,一般情況可表示為 void backtrack int n else 引數n表示遞迴的深度 is ok 表示已經求得問題解 print reult 表示列印結果 如果只求出乙個可行解,那麼求得第乙個問題解後便可exit 如果要求出所有可行解則不需exit base...

遞迴回溯總結

8皇后問題是一道非常經典的題目。題目是說,乙個n n的西洋棋棋盤上主放置n個皇后,使其不能相互攻擊,即任何兩個皇后都不能處在棋盤的同一行,同一列,同一條斜線上,試問共有多少種擺法?其實,題目就是要找出所有的可能情況,然後排除其中不符合條件的情況,剩下的情況即為所要求的。怎麼找出所有的情況呢?對於8皇...