M - 排列组合
有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B,并且数量都是1,从中选2件物品,则排列有"AB","BA"两种。
每组输入数据有两行,第一行是二个数n,m(1<=m,n<=10),表示物品数,第二行有n个数,分别表示这n件物品的数量。
对应每组数据输出排列数。(任何运算不会超出2^31的范围)
input
2 2
1 1
output
2
超级水
我们直接暴力枚举每种物品选几个,记为\(b_i\)
每种枚举方案的贡献为
\(Ans = m! / (\phi_{i = 1}^{n} b_i!)\)
求和即可
#include<iostream>
#include<cstdio>
using namespace std;
#define int long long
int fac[50];
int n,m;
int a[20];
int b[20];
int ans;
void dfs(int st,int s){
if(st == n + 1){
if(s != m) return ;
int t = fac[m];
for(int i = 1; i <= n; ++ i)
if(b[i] > 0) t /= fac[b[i]];
ans += t;
return ;
}
for(int i = 0; i <= m - s && i <= a[st]; ++ i){
b[st] = i;
dfs(st + 1, s + i);
}
}
signed main(){
fac[0] = 1;
for(int i = 1; i <= 12; ++ i) fac[i] = fac[i - 1] * i;
while (scanf("%lld%lld",&n,&m)!= EOF){
ans = 0;
for(int i = 1; i <= n; ++ i) scanf("%lld",&a[i]);
dfs(1,0);
printf("%lld\n",ans);
}
return 0;
}