• 杭电 1521 排列组合


    Problem Description
    有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B,并且数量都是1,从中选2件物品,则排列有"AB","BA"两种。
     
    Input
    每组输入数据有两行,第一行是二个数n,m(1<=m,n<=10),表示物品数,第二行有n个数,分别表示这n件物品的数量。
     
    Output
    对应每组数据输出排列数。(任何运算不会超出2^31的范围)
     
    Sample Input
    2 2 1 1
     
    Sample Output
    2
     
    Author
    xhd
     
    Recommend
    xhd
     
         问题描述:n个物品,每种物品的数量已知,然后从中选取m个物品进行排列,问有多少种排列方法?
         问题解答:从网上的相关资料中得知,本题属于组合数学中母函数问题!所以就搜了一些关于指数型母函数的理论知识,觉得看懂后就找了份相关代码拿来看,看懂后发现指数型母函数相乘的代码和一般母函数的代码实现由很大的相似!而在我看的那份代码里for循环的控制语句,写的很好,可以减少一些不必要的计算!
     
     1 #include <stdio.h>
     2 #include <string.h>
     3 int fac[] = {1,1,2,6,24,120,720,5040,40320,362880,362880};
     4 int main()
     5 {
     6     int n, m, i, j, k;
     7     int a[15];
     8     double c1[15], c2[15];
     9     while( scanf( "%d%d", &n, &m ) != EOF )
    10     {
    11         memset(a,0,15*sizeof(int));
    12         memset(c1,0,15*sizeof(double));
    13         memset(c2,0,15*sizeof(double));
    14 
    15         for( i = 1; i <= n; i++ )
    16             scanf( "%d", &a[i] );
    17         for( i = 0; i <= a[1]; i++ )
    18             c1[i] = 1.00/fac[i];
    19         for( i = 2; i <= n; i++ )
    20         {
    21             for( j = 0; j <= m; j++ )
    22                 for( k = 0; (k + j <= m)&&(k <= a[i]); k++ )
    23                     c2[k+j] += c1[j]/fac[k];
    24             for( j = 0; j <=m; j++ )
    25             {
    26                 c1[j] = c2[j];
    27                 c2[j] = 0;
    28             }
    29         }
    30         printf( "%.0lf\n",fac[m] * c1[m] );
    31     }
    32     return 0;
    33 }
    View Code
  • 相关阅读:
    9.3 simulated match
    网络流模版大全
    Treblecross
    ENimEN
    求逆序对的两种方法(树状数组/归并排序)
    树状数组
    计算最短路和次短路条数
    Python3.7版库的安装以及常用方法(十分简单)
    二维线段树(hdu1823)
    流星雨(记忆化搜索)
  • 原文地址:https://www.cnblogs.com/yizhanhaha/p/3100243.html
Copyright © 2020-2023  润新知