1. 程式人生 > 實用技巧 >全排列問題

全排列問題

  • 首先可以考慮自己寫dfs函式對全排列問題進行求解。

參考程式碼如下:

#include<iostream>
using namespace std;
int a[10010],b[10010];
long long int total=0;
int n;
void dfs(int k)
{
    if(k>n)
    {
       total++;//記錄方案個數
       for(int i=1;i<=n;i++)
       cout<<b[i]<<" ";
       cout<<endl;
     return;
    }
    for(int i=1;i<=n;i++)//嘗試在b[k]中填寫各種整數的i
    {
        int ok=1;
        for(int j=1;j<k;j++)
        if(b[j]==i)
        {
           ok=0;//如果i已經在b[1]~b[k-1]出現過,則不能再選
           //break;
        }
        if(ok)
        {
             b[k]=i;
             dfs(k+1);//進行下一個元素的全排列
        }
    }

}
int main()
{
	ios::sync_with_stdio(false);
	cin >> n;//輸入元素個數
	for (int i = 1;i <= n;i++)
		cin >> a[i];
    for(int i=1;i<=n;i++)
         dfs(i);
    cout<<"所有排列方案數為:"<<total<<endl;
    return 0;
}

練習題目:

1.Luogu:火星人

  • C++的STL庫中有next_permutation()函式可以對數字進行全排列,下面對這個函式的用法進行詳細的介紹。具體請參考下面這篇部落格:

kuangbin之next_permutation函式

- 康託展開(全排列和序號之間的對映)

康託展開解決的兩個問題:

正康託展開:給出一個全排列的序列,求該序列是第幾個全排列的序列。

如初始序列1234,那麼3214是第15個全排列的序列。

逆康託展開:給出數字k,求全排列序列中的第k個序列是什麼。

如初始序列1234,第15個全排列的序列為3214。

康託展開是為了解決全排列和序號之間的對映問題,對於全排列,可以通過next_permutation(a,a+n)(或者pre_permutation(a,a+n))去求解,當然也可以自己寫一個遞歸回溯函式求解。
具體的講解可以瞭解維基百科中對此的講解。

傳送門