• 杭电1465


    题意:向n个人发n封信,全部都发错的情况有多少种

     
    Analyse:
    记错排的符号为f(n),则f(n)=A(n,n)-C(n,1)*f(n-1)-C(n,2)*f(n-2)……-C(n,n-2)*f(2)-1(表示n个元素的全排列排除有k(1<=k<=n-2)个放对位置的情况,不存在n-1个放对位置的情况,最后的1表示全部放对的情况),有f(n-1)=A(n-1,n-1)-C(n-1,1)*f(n-2)-C(n-1,2)*f(n-3)……-C(n-1,n-3)*f(2)-1,将f(n-1)代入到f(n)得到,f(n)=C(n,2)*f(n-2)+2*C(n,3)*f(n-3)+……+(n-3)*C(n,n-2)*f(2)+n-1。
    View Code
     1 #include<stdio.h>
    2 __int64 c[21][21];
    3 main()
    4 {
    5 __int64 awnum[21]={0,0,1,2};//全错的情况
    6 int i,j;
    7 int n;
    8 //构建杨辉三角
    9 c[0][0]=1;
    10 for(i=1;i<=20;i++)
    11 {
    12 c[i][0]=1;
    13 c[i][i]=1;
    14 for(j=1;j<i;j++)
    15 c[i][j]=c[i-1][j-1]+c[i-1][j];
    16 }
    17 //递推出各种全错数目
    18 for(i=4;i<=20;i++)
    19 {
    20 awnum[i]=i-1;
    21 for(j=i-2;j>=2;j--)
    22 awnum[i]+=(i-j-1)*c[i][i-j]*awnum[j];
    23 }
    24 while(scanf("%d",&n)==1)
    25 printf("%I64d\n",awnum[n]);
    26 }
    后来知道错排有递推公式,f(n)=(n-1)*(f(n-1)+f(n-2)),f(1)=0,f(2)=1。解释如下:
    先将第一个位置的元素放到第k个位置(对k的选择有(n-1)种情况);然后第k个位置的元素如果放在第一个位置,则有f(n-2)种情况,而第k个位置的元素若不放在第一个位置,则将第一个位置看成是k原本的位置(因为k不放在第一个位置),因此相当于n-1个元素的错排,有f(n-1)种情况。由加法原理和乘法原理可得上述公式。
     
  • 相关阅读:
    crmfuxi
    段子
    wsfenxiang
    生成器、列表推导式
    闭包、迭代器、递归
    函数的参数及返回值
    嵌套、作用域、命名空间
    定义、函数的调用
    测试样式
    进制转换
  • 原文地址:https://www.cnblogs.com/ZShogg/p/2432022.html
Copyright © 2020-2023  润新知