zoukankan      html  css  js  c++  java
  • HDU 2068 RPG的错排 排列组合

    解题报告:

    题目大意:有N个人和N个名字,要将他们一一对应,对应的规则是至少要有N/2是对了的,求这样一共有多少种对应的方法。

    错排题,从0开始枚举到N/2,即表示有0个人的名字与人对应是错的、1个人的名字与本人的对应是错的、两个人的名字与本人的对应是错的、、、2、、、、,这里用一个组合就可以了,要注意的是求组合的时候必须一边乘一边除掉,否则用__int64也会溢出,然后就是一个错排,错排的递推公式是dp[n]=(n-1)*(dp[n-1]+dp[n-2]);假设现在有5个位置,编号为1、2、3、4、5,有5个人编号为1、2、3、4、5,规定1号不能做1号位置,2号不能做2号位置、、、、,则dp[5]可以有dp[4]得出来,思想是假设现在有一个四个人的和四个位置的错排,现在添加一个5,第一种,先考虑当让这个5去做1号位置,然后分两种情况,第一种,1坐5的位置,这样就相当于3个人的错排,也就是dp[n-2],第二种,1不坐5的位置,这样就等于可以把1看成是5了,也就是4个人的错排,也就是dp[n-1],然后考虑的是先让5去坐2的位置,接下来就跟上面情况一样了,所以乘以一个(n-1),就得到了dp[n]=(n-1)*(dp[n-1]+dp[n-2]);

     1 #include<cstdio>
     2 #include<cmath>
     3 __int64 dp[30];
     4 void dabiao() {
     5     dp[0]=dp[1]=0,dp[2]=1;
     6     for(__int64 i=3;i<=30;++i)
     7     dp[i]=(dp[i-1]+dp[i-2])*(i-1);
     8     dp[0]=1;
     9 }
    10 __int64 C(__int64 x,__int64 y) {
    11     if(y==0)
    12     return 1;
    13     __int64 s=1;
    14     for(__int64 i=x;i>=x-y+1;--i) {
    15         s*=i;
    16         s/=(x-i+1);
    17     }
    18     return s;
    19 }
    20 int main() {
    21     dabiao();
    22     __int64 n;
    23     while(scanf("%I64d",&n)&&n) {
    24         __int64 sum=0,leiji=1,chu=1;
    25         for(__int64 i=0;i<=n/2;i++)
    26         sum+=dp[i]*C(n,i);
    27         printf("%I64d\n",sum);
    28     }
    29     return 0;
    30 }
    View Code
  • 相关阅读:
    【数据大屏设计】有点意思
    MySQL环境搭建
    关于MySQL数据库
    zip-gzip-bzip2_压缩文件
    Linux的链接文件-ln命令
    电脑为什么越用越慢
    按下开机键,计算机背后的故事
    Windows最全快捷键
    环境搭建-VMware安装系统
    wee hours
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/3109212.html
Copyright © 2011-2022 走看看