hdu1521排列组合(指数型母函数)

题目链接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

猜你喜欢

转载自blog.csdn.net/qq_41626975/article/details/82078279