程序中的常用算法--递归算法
题目:将编号(1……n)n封信装入编号(1……n)n个信封,算出全部装错的情况,即全部装完后所有信封编号与信封内信的编号全部不同。
思考情景,递归算法,考虑n封信全部装错信封f(n)和n-1封信全部装错信封f(n-1)。首先第一封信一共有n-1个信封可以装入,假设第一封信装入了第k个信封,这个时候会有两个场景:
一,第k封信刚好装入了第一个信封,此时刚好变成了处理f(n-2);
二,第k封信没有装入第一个信封,此时第k个信封已经装入第一封信不做考虑;将第一个信封移至第k个信封位置,而第k封信要求不能装入第一个信封,处理编号为(2……k-1,k,k+1……n)封信装入编号为(2……k-1,1,k+1……n)信封的问题f(n-1);
三,归纳为f(n) = (n-1)(f(n-2) + f(n-1));
c语言代码如下
#include<stdio.h>
int a[100] = {0};//递归函数每次调用都会计算,用全局变量保存可以减少计算时间
int main()
{
int putin(int n);
int n;
scanf("%d", &n);
printf("get all status:%d", putin(n));
return ;
}
int putin(int n)
{
//n《=1 情况为0
if(n <= 1)
{
return 0;
}
//n=2时只有一种装错的情况
if(n == 2)
{
a[2] = 1;
return 1;
}
//已经计算过直接取出
if(a[n])
{
return a[n];
}
else
{
a[n] = (n-1)*(putin(n-1) + putin(n-2));
return a[n];
}
}