HDU 2068 RPG的错排

HDU 2068 RPG的错排

RPG的错排
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5666 Accepted Submission(s): 2325

Problem Description
今年暑假杭电ACM集训队第一次组成女生队,其中有一队叫RPG,但做为集训队成员之一的野骆驼竟然不知道RPG三个人具体是谁谁。RPG给他机会让他猜猜,第一次猜:R是公主,P是草儿,G是月野兔;第二次猜:R是草儿,P是月野兔,G是公主;第三次猜:R是草儿,P是公主,G是月野兔;......可怜的野骆驼第六次终于把RPG分清楚了。由于RPG的带动,做ACM的女生越来越多,我们的野骆驼想都知道她们,可现在有N多人,他要猜的次数可就多了,为了不为难野骆驼,女生们只要求他答对一半或以上就算过关,请问有多少组答案能使他顺利过关。

Input
输入的数据里有多个case,每个case包括一个n,代表有几个女生,(n<=25), n = 0输入结束。

Sample Input
1 2 0


Sample Output
1 1

本题主要是全错位排列。开始先考虑人数n奇偶,奇数就从猜对n/2+1开始,偶数就从n/2开始,一直循环到n.

假设猜对s个,没猜对t个,其中t = n-s。 组数为C(n,s)*剩余t个人全部没猜中的所有情况。剩余t个人全部没有猜中就是全错位排列

百度一下可知道其递推公式为  f(n)=nf(n-1)+(-1)^(n-2) 又知道  1个元素没有全错位排列,2个元素的全错位排列有1种,3个元素的全错位排列有2种,4个元素的全错位排列有9种,5个元素的全错位排列有44种。

于是可以用for循环递推到13

HDU2068.cpp
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
#define MAXN 25+5
int F[MAXN];
double zuhe(int up,int down);
double jiecheng(int a);
int main()
{
    F[1] = 0;
    F[2] = 1;
    for(int i = 3;i <= 13;i++)
    {
        F[i] = i*F[i-1] + pow(-1,i-2);
    }
    F[0] = 1;
    int n;
    while(cin>>n,n!=0)
    {
        __int64 an = 0;
        int s,t;//s表示猜对的人数 t表示没猜对的人数
        if (n%2)
        {
            s = n/2 + 1;
        }
        else
        {
            s = n/2;
        }
        t = n - s;
        do
        {
            an += zuhe(s,n)*F[t];
        }
        while(s++,t--);
        printf("%I64d\n",an);
    }
    return 0;
}
double jiecheng(int a)
{
    double s = 1;
    for(int i = 1;i <= a;i++)
    {
        s *= i;
    }
    return s;
}
double zuhe(int up,int down)
{
    return jiecheng(down)/(jiecheng(up)*jiecheng(down-up));
}

你可能感兴趣的:(HDU 2068 RPG的错排)