杭电 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
原文地址:https://www.cnblogs.com/yizhanhaha/p/3100243.html