<span>全排列问题</span>
- 首先可以考虑自己写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;
}
练习题目:
- C++的STL库中有next_permutation()函数可以对数字进行全排列,下面对这个函数的用法进行详细的介绍。具体请参考下面这篇博客:
- 康托展开(全排列和序号之间的映射)
康托展开解决的两个问题:
正康托展开:给出一个全排列的序列,求该序列是第几个全排列的序列。
如初始序列1234,那么3214是第15个全排列的序列。
逆康托展开:给出数字k,求全排列序列中的第k个序列是什么。
如初始序列1234,第15个全排列的序列为3214。
康托展开是为了解决全排列和序号之间的映射问题,对于全排列,可以通过next_permutation(a,a+n)(或者pre_permutation(a,a+n))去求解,当然也可以自己写一个递归回溯函数求解。
具体的讲解可以了解维基百科中对此的讲解。