题解:P11316 [RMI 2021] 去 M / NoM
Solution
首先我们转化一下题意,我们把
第
我们设
考虑处理第
在状态
当前类要放
易得转移方程为:
当我们知道将所有
- 每个剩余类内部的
w_i 个位置上的石子可以任意排列,有\prod_{i=1}^{M} w_i! 种方式。 - 每对石子中颜色可以互换,共
2^N 种方式。
所以最终答案就为:
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=4e3+5;
const int M=1e9+7;
int n,m,v[N],inv[N],dp[N][N];
int qpow(int a,int b){
int res=1;
while(b){
if(b&1)res=res*a%M;
a=a*a%M;
b>>=1;
}
return res;
}
void init(){
v[0]=1;
for(int i=1;i<N;i++){
v[i]=v[i-1]*i%M;
}
inv[N-1]=qpow(v[N-1],M-2);
for(int i=N-2;i>=0;i--){
inv[i]=inv[i+1]*(i+1)%M;
}
}
int C(int a,int b){
return v[a]*inv[b]%M*inv[a-b]%M;
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
init();
cin>>n>>m;
dp[0][0]=1;
int s=0,mul=1;
for(int i=1;i<=m;i++){
int w=(2*n-i)/m+1;
mul=mul*v[w]%M;
for(int j=0;j<=s/2;j++){
for(int k=0;k<=min(w,s-2*j);k++){
int cost=C(s-2*j,k)*C(n-(s-j),w-k)%M;
dp[i][j+k]=(dp[i][j+k]+dp[i-1][j]*cost)%M;
}
}
s+=w;
}
int ans=dp[m][n]*mul%M*qpow(2,n)%M;
cout<<ans;
}