机试算法讲解: 第48题 递推之写信发错啦

来源:互联网 发布:淘宝助理上传宝贝 编辑:程序博客网 时间:2024/06/05 16:14
/*问题:给N个网友写信,所有信全部装错信封有多少种可能的错误方式输入:n(1<n<=20)输出:错误的方式输入:23输出:12递推求解:n=1,0种,n=2,1种,n=3,2种,n=4,8种。设F[n]为n个信封的装错方式总数。         假设n号信封装的是k号信封,而n号信封中的信装在m号信封里。将k==m分为两类 1)若k!=m,交换n号信封和m号信封,则n号信封对了,m号信封中是装的k号信,即除n号信封外,其余n-1个信封全部装错。装错方式为F[n-1]。又由于m的n-1个可能取值 这类装错方式总数为(n-1)*F[n-1]。在n-1个信封装错的F[n-1]基础上,将n号信封所装的信与n-1个信封中任意一个信封(n-1中选择)所装的新交换,所得信全部错误。 2)若k=m,交换n号信和m号信后,n号信封和m号中恰好对了,除它们之外剩余的n-2个信封全部装错,装错方式为F[n-2],又由于m的n-1个取值,装错方式总数为 (n-1)*F[n-2]。可理解为在n-2个信封全部装错基础上,交换n号信封和1到n-1号信封中任意1刚和,共有n-1种选择。关键:1 错排公式F[n]={0,n=1               {1,n=2   {(n-1)*F[n-1] + (n-1)*F[n-2],n>=22 递推求解技巧:逆推,从倒数第二步或者倒数第一步如何到达最终状态,找到递推关系式3 递推求解往往数值较大,用long long 或 _int64 ,打印用%ld4 分析问题,将每一个问题分割成规模较小的几个问题,分割过程要不遗漏和不重复,要得到递推关系式*/#include <stdio.h>#include <stdlib.h>#include <string.h>#define N 21int main(int argc,char* argv[]){_int64 F[N];F[1] = 0;F[2] = 1;for(int i = 3 ; i <= N ; i++){F[i] = (i-1)*F[i-1] + (i-1)*F[i-2];}int n;while(EOF!=scanf("%d",&n)){printf("%ld\n",F[n]);}system("pause");getchar();return 0;}

0 0
原创粉丝点击