题目链接https://vjudge.net/problem/HDU-1521
题目如下
有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
这道题需要用到指数型母函数,关于指数型母函数的讲解见http://www.wutianqi.com/?p=2644
母函数用普通型母函数,指数型母函数。普通型母函数主要是来求组合的方案数,而指数型母函数是求多重排列数。
代码如下
#include<cstdio>
#include<iostream>
#include<cstring>
#include<iomanip>
using namespace std;
double c1[100],c2[100];
int a[11];
int fun(int n)//求阶乘,但是不要忘记0的阶乘
{
int ans=1;
for(int i=1;i<=n;i++)
ans*=i;
return ans;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
for(int i=0;i<=a[1];i++)c1[i]=1.0/fun(i);//初始化1+x1^1/1!+x1^2/2!+...
for(int i=2;i<=n;i++)
{
for(int j=0;j<=m;j++)
for(int k=0;k<=a[i]&&k+j<=m;k++)//k是指数
c2[k+j]+=c1[j]/fun(k);
for(int y=0;y<=m;y++)
{
c1[y]=c2[y];
c2[y]=0;
}
}
cout<<fixed<<setprecision(0)<<c1[m]*fun(m)<<endl;
}
return 0;
}
关于第35行输出的控制见https://mp.csdn.net/postedit/81911955