「HDU1521」排列组合
「HDU1521」排列组合
problem
Solution
生成函数入门题
第\(i\)种物品有\(n_i\)个,构造指数型生成函数
\[G_e(x)=\sum_{k=1}^{min(n_i,m)}\frac{x^k}{k!} \]把所有物品的生成函数乘起来
设最后得到的多项式的\(m\)次项为\(a_m\)
那么答案即为
\[a_m*m! \]Code
很丑,很不优雅,慎看
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
template void read(T &t)
{
t=0;int f=0;char c=getchar();
while(!isdigit(c)){f|=c=='-';c=getchar();}
while(isdigit(c)){t=t*10+c-'0';c=getchar();}
if(f)t=-t;
}
const int maxn=10+5,maxm=maxn;
ll n,m;
double fac[maxm];
double a[maxm],b[maxm],c[maxm];
void Pre()
{
fac[0]=1;
for(register int i=1;i<=10;++i)
fac[i]=fac[i-1]*i;
}
ll gcd(ll a,ll b)
{
return b?gcd(b,a%b):a;
}
int main()
{
Pre();
while(scanf("%lld%lld",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
ll k;
read(k);
for(register int i=0;i<=min(k,m);++i)a[i]=1.0/fac[i];
--n;
while(n--)
{
read(k);
memset(b,0,sizeof(b));
for(register int i=0;i<=min(k,m);++i)b[i]=1.0/fac[i];
memset(c,0,sizeof(c));
for(register int i=0;i<=m;++i)
for(register int j=0;i+j<=m;++j)
c[i+j]+=a[i]*b[j];
memcpy(a,c,sizeof(c));
}
printf("%.0f\n",fac[m]*a[m]);
}
return 0;
}