NOJ 451 光棍节的快乐(组合数+全错位排列)

来源:互联网 发布:usb口检测软件 编辑:程序博客网 时间:2024/05/17 00:52

题目链接~~>

解题思路:

          瑞士数学家欧拉按一般情况给出了一个递推公式:用A、B、C……表示写着n位友人名字的信封,a、b、c……表示n份相应的写好的信纸。把错装的总数为记作f(n)。假设把a错装进B里了,包含着这个错误的一切错装法分两类:
        (1)b装入A里,这时每种错装的其余部分都与A、B、a、b无关,应有f(n-2)种错装法。
        (2)b装入A、B之外的一个信封,这时的装信工作实际是把(除a之外的) 份信纸b、c……装入(除B以外的)n-1个信封A、C……,显然这时装错的方法有f(n-1)种。总之在a装入B的错误之下,共有错装法f(n-2)+f(n-1)种。a装入C,装入D……的n-2种错误之下,同样都有f(n-2)+f(n-1)种错装法,因此:           f( n )=( n-1 ) { f( n-1 ) + f( n-2 ) } 。
代码:
#include<stdio.h>int main(){    long long int f[22],i,nx,mx,n,m ;//本题需用long long     f[1]=0 ;f[2]=1 ;    for(i=3 ;i<=20 ;i++) // 递推公式        f[i]=(i-1)*(f[i-1]+f[i-2]) ;    while(scanf("%lld%lld",&n,&m)!=EOF)    {        nx=1 ;mx=1 ;        for(i=n-m+1 ;i<=n ;i++)                nx*=i ;        for(i=m ;i>=2 ;i--)                mx*=i ;        printf("%lld\n",nx/mx*f[m]) ;    }    return 0 ;}