今天,来尝试一下用递归实现错排问题。
-
(常考点) 递归关系:D(n)=(n-1)(D(n-1)+D(n-2)) 特别地有D(1)=0,D(2)=1;
-
错排公式:D(n) = n! [(-1)^2/2! + … + (-1)^(n-1)/(n-1)! + (-1)^n/n!], 特别地有0!=1 1!=1 代码实现:
//用递归方式输出错排序列
#include <stdio.h>
#define N 100
int a[N] = { 0 };//存放错排序列
int flag[N] = { 0 };//用于标志某元素是否被使用
int n, count = 0;
void Recursion(int x)
{
//若1..n位均已成功放置
if (x > n)
{
count++;
//输出得到的错排
for (int i = 1; i <= n; i++)
printf("%d ", a[i]);
printf("\n");
return;
}
else
for (int i = 1; i <= n; i++)
{
//若i可以放置在x位
if (flag[i] == 0 && x != i)//没被使用过
{
flag[i] = 1; //做放置标记
a[x] = i; //放置
Recursion(x + 1); //尝试放置x+1位
flag[i] = 0; //撤销放置标记
}
}
}
int main() {
int i;
printf("input n:");
scanf_s("%d", &n);
//从1位开始尝试得到序列1..n的错排
Recursion(1);
printf("count:%d\n", count);
return 0;
}