题目来源
洛谷P1358扑克牌
https://www.luogu.org/problem/show?pid=1358
思路
预处理出C(i,j)
(从i个物品中取j个物品的方案数,i>=0,i<=n;j>=0,j<=max(a[1~m]))
对于第i个人 他取扑克牌时相当于从前i-1个人拿剩下的(n-sum)张牌中选a[i]张
他取扑克牌的方案数即为C(n-sum,a[i])
总方案数即为每个人拿牌的方案数乘积
注意:边乘边取模
代码(C++)
#include <cstdio>
using namespace std;
int n,m,sum=0,k=0,ans=1,a[110],c[10010][10010];
inline void pre();
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
{
scanf("%d",&a[i]);
if(a[i]>k) k=a[i];
}
pre();
for(int i=1;i<=m;++i)
ans=(ans*c[n-sum][a[i]])%10007,sum+=a[i];
printf("%d",ans);
return 0;
}
inline void pre()
{
c[0][0]=1;
for(int i=1;i<=n;++i)
{
c[i][0]=1;
for(int j=1;j<=i&&j<=k;++j)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%10007;
}
return ;
}