HDU 2049

HDU2049

错排+组合
错排公式 f(n)=(n-1)*[f(n-1)+f(n-2)]


首先考虑,如果开始有n-1个新郎,并且这n-1个人都已经完成了错排(有f(n-1)种可能),
现在又来了一个人,那么后来的第n个人可以通过用自己的新娘去和那n-1个人中的任意一个
交换,来实现n个人都错排。这种情况有(n-1)*f[n-1]种可能;
另外,如果开始的n-1个人不是都错排,那么要想使第n个人过来与其中一个交换后实现错排的话就必须满足两个条件:
1.那n-1个人中只有一个人选到了自己的新娘,也就是说有n-2个人都已经错排了。
2.第n个人必须和那个选到自己新娘的人去交换,但那个选到自己新娘的人可以是n-1个人中的任意一个。这种情况有(n-1)*f[n-2]种可能。
其他情况都不能满足n个人错排。
因此递推关系:f[n]=(n-1)*(f[n-1]+f[n-2])。
 

AC代码:

#include <iostream>
using namespace std;

long long f[30];

long long jc(long long a)//求阶乘
{
    if(a==1)
        return 1;
    else
        return a*jc(a-1);
}

long long C(long long n,long long m)//求组合数
{
    if(m==0||m==n)return 1;
    long long a,b,c;
    a=jc(n);b=jc(m);c=jc(n-m);
    return a/c/b;
}

int main()
{
    f[0]=0;f[1]=0;f[2]=1;

    for(int i=3;i<=20;i++)
    {
        f[i]=(i-1)*(f[i-1]+f[i-2]);
    }
    long long n,m;
    int c;
    cin>>c;
    while(c--)
    {
        cin>>n>>m;
        cout<<C(n,m)*f[m]<<endl;
    }


    return 0;
}

猜你喜欢

转载自blog.csdn.net/TernYoung/article/details/83476366