• HDU RPG的错排 【错排&&组合】


    RPG的错排

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 16097    Accepted Submission(s): 6527


    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
     
    Author
    Rabbit
     
    刚开始写的时候去写组合了……想都不想,还以为是自己逆元写挂了。不过没有模这个条件不错,可以用来避免犯傻子错误。
    这个题是个错排问题,错排公式
        cp[i]=(i-1)*(cp[i-1]+cp[i-2]);
    证明:
    当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
    第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
    第二步,放编号为k的元素,这时有两种情况:⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;
    综上得到
    D(n) = (n-1) [D(n-2) + D(n-1)]
    自己去写那个复杂的公式写挂了。。
    这个代码里也用了求组合数数据较小时候的代码。
    #include <algorithm>
    #include <iostream>
    #include <iomanip>
    #include <cstring>
    #include <climits>
    #include <complex>
    #include <fstream>
    #include <cassert>
    #include <cstdio>
    #include <bitset>
    #include <vector>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <ctime>
    #include <set>
    #include <map>
    #include <cmath>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define maxn 10005
    #define maxm 30000
    #define ll long long
    #define mod 1000000007
    #define mem(a,b) memset(a,b,sizeof a)
    #ifndef ONLINE_JUDGE
       #define dbg(x) cout<<#x<<"="<<x<<endl;
    #else 
       #define dbg(x) 
    #endif
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=10*x+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    inline void Out(int a) 
    {
        if(a>9)
            Out(a/10);
        putchar(a%10+'0');
    }
    ll cp[20],C[55][55];
    void init()
    {
        cp[0]=1;cp[1]=0;cp[2]=1;
        for(int i=3;i<15;++i) cp[i]=(i-1)*(cp[i-1]+cp[i-2]);
        mem(C,0);
        C[0][0]=1;
        for(int i=1;i<=30;++i)
        {
              C[i][0]=C[i][i]=1;
              for(int j=1;j<=i;++j)
              {
                    C[i][j]=C[i-1][j-1]+C[i-1][j];
              }
        }
    }
    int main()
    {
       int n;
       init();
       while(~scanf("%d",&n)&&n)
       {
           ll ans=cp[0];
           int hal=n>>1;
           for(int i=1;i<=hal;++i)
           {ans+=cp[i]*C[n][i];}
           cout<<ans<<endl; 
       }
    }
  • 相关阅读:
    图床_OpenStack-镜像服务
    图床_OpenStack-认证服务
    图床_OpenStack-基础环境
    #linux包之tcpdump之tcpdump命令
    利用OpenCms9提供的模块创建新站点
    Cocos2d-x3.0下实现循环列表
    Modbus读写模拟量寄存器具体解释
    C++ 实践总结
    spring Quartz基于配置文件和注解的实现
    EEPLAT学习
  • 原文地址:https://www.cnblogs.com/TYH-TYH/p/9444129.html
Copyright © 2020-2023  润新知