题解 AT2000 【[AGC002F] Leftmost Ball】
lemondinosaur · · 题解
洛谷题目传送门
ATCODER传送门
设
首先
然后
既然要多添加一种颜色,那么就要选择剩下
并且要在剩下的
补充说明:
- 排列长度
n\times k ,放入i 个白球和j-1 种颜色(每种颜色为k-1 个) - 为什么是
k-2 ,如果不指定当前剩下的第一个位置为该颜色, 那么当选择其它颜色填入时这种方案就会算重,所以是k-2 ,并且剩下的总位置也要减 1。
预处理阶乘和乘法逆元就可以了。
#include <cstdio>
#define rr register
using namespace std;
const int mod=1000000007,N=2001;
int n,k,inv[N*N],fac[N*N],dp[N][N];
inline signed mo(int x,int y){
return x+y>=mod?x+y-mod:x+y;
}
inline signed c(int n,int m){
return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;
}
signed main(){
inv[0]=inv[1]=fac[0]=fac[1]=1,scanf("%d%d",&n,&k);
if (k==1) return !putchar(49);
for (rr int i=2;i<=n*k;++i)
inv[i]=1ll*inv[mod%i]*(mod-mod/i)%mod;
for (rr int i=2;i<=n*k;++i) fac[i]=1ll*fac[i-1]*i%mod;
for (rr int i=2;i<=n*k;++i) inv[i]=1ll*inv[i-1]*inv[i]%mod;
for (rr int i=0;i<=n;++i) dp[i][0]=1;
for (rr int i=1;i<=n;++i)
for (rr int j=1;j<=i;++j)
dp[i][j]=mo(dp[i-1][j],1ll*dp[i][j-1]*(n-j+1)%mod*c(n*k-i-1-(j-1)*(k-1),k-2)%mod);
return !printf("%d\n",dp[n][n]);
}