洛谷【P1358】扑克牌
我对状态空间的理解:https://www.cnblogs.com/AKMer/p/9622590.html
题目传送门:https://www.luogu.org/problemnew/show/P1358
因为本分组讲的主要是暴力之美……所以关于组合数的部分就不多言了。
总之,这道题很暴力。
时间复杂度:\(O(n)\)
空间复杂度:\(O(n)\)
代码如下:
#include <cstdio>
using namespace std;
const int pps=1e4+7;
int n,m,ans=1;
int a[pps],fac[pps],inv[pps];
int read() {
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
return x*f;
}
int quick(int a,int b) {
int sum=1;
while(b) {
if(b&1)sum=sum*a%pps;
a=a*a%pps;b>>=1;
}
return sum;
}
void prepare() {
fac[0]=fac[1]=inv[0]=inv[1]=1;
for(int i=2;i<=n;i++)
fac[i]=fac[i-1]*i%pps;
inv[n]=quick(fac[n],pps-2);
for(int i=n-1;i;i--)
inv[i]=inv[i+1]*(i+1)%pps;
}
int c(int a,int b) {
return fac[a]*inv[b]%pps*inv[a-b]%pps;
}
int main() {
n=read(),m=read();
for(int i=1;i<=m;i++)
a[i]=read();
prepare();
for(int i=1;i<=m;i++) {
ans=ans*c(n,a[i])%pps;
n-=a[i];
}printf("%d\n",ans);
return 0;
}