Problem Statement

Snuke loves colorful balls. He has a total of N×K balls, K in each of his favorite N colors. The colors are numbered 1 through N.

He will arrange all of the balls in a row from left to right, in arbitrary order. Then, for each of the N colors, he will paint the leftmost ball of that color into color 0, a color different from any of the N original colors.

After painting, how many sequences of the colors of the balls are possible? Find this number modulo 109+7.

Constraints

  • 1≤N,K≤2,000

Input

The input is given from Standard Input in the following format:

N K

Output

Print the number of the possible sequences of the colors of the balls after painting, modulo 109+7.

Sample Input 1

2 2

Sample Output 1

4

The following 4 sequences are possible:

  • (0,1,0,2)
  • (0,0,1,2)
  • (0,2,0,1)
  • (0,0,2,1)

Sample Input 2

3 1

Sample Output 2

1

The following 1 sequence is possible:

  • (0,0,0)

Sample Input 3

2 3

Sample Output 3

14

Sample Input 4

2000 2000

Sample Output 4

546381702

    不妨把0颜色看成白球,把其他颜色看成彩球,那么我们来讨论一下什么样的序列是合法的。
仅有一个序列中的每一个白球都能在其后方匹配到一个是其颜色里出现第一次的彩球,这个序列才合法。
所以我们就可以从后向前dp,状态的定义和转移在代码里都有,只不过特判一下k==1直接输出1就好了。
/*
f[i][j] 表示 已经出现过 i种颜色的球,
并且还剩j种颜色的球没有被匹配的方案数。 考虑加入一种新球的话:
f[i+1][j+1] += f[i][j] * (n-i) * C(k*(i+1)-j-2,k-2) 考虑加入一种白球的话:
f[i][j-1] += f[i][j] 初始化 f[0][0] = 1
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2005;
const int ha=1000000007;
int jc[maxn*maxn],ni[maxn*maxn];
int n,k,f[maxn][maxn]; inline int add(int x,int y){
x+=y;
return x>=ha?x-ha:x;
} inline int ksm(int x,int y){
int an=1;
for(;y;y>>=1,x=x*(ll)x%ha) if(y&1) an=an*(ll)x%ha;
return an;
} inline void init(){
jc[0]=1;
for(int i=1;i<=4004000;i++) jc[i]=jc[i-1]*(ll)i%ha;
ni[4004000]=ksm(jc[4004000],ha-2);
for(int i=4004000;i;i--) ni[i-1]=ni[i]*(ll)i%ha;
} inline int getC(int x,int y){
return jc[x]*(ll)ni[y]%ha*(ll)ni[x-y]%ha;
} inline void dp(){
f[0][0]=1;
for(int i=0;i<=n;i++)
for(int j=i;j>=0;j--) if(f[i][j]){
f[i+1][j+1]=add(f[i+1][j+1],f[i][j]*(ll)(n-i)%ha*(ll)getC(k*(i+1)-j-2,k-2)%ha);
if(j) f[i][j-1]=add(f[i][j-1],f[i][j]);
} /*
for(int i=0;i<=n;i++){
for(int j=0;j<=i;j++) printf("%d ",f[i][j]);
puts("");
}
*/
} int main(){
init();
scanf("%d%d",&n,&k);
if(k==1) puts("1");
else{
dp();
printf("%d\n",f[n][0]);
}
return 0;
}

  

 

ATcoder 2000 Leftmost Ball的更多相关文章

  1. AtCoder AGC002F Leftmost Ball (DP、组合计数)

    题目链接: https://atcoder.jp/contests/agc002/tasks/agc002_f 题解: 讲一下官方题解的做法: 就是求那个图(官方题解里的)的拓扑序个数,设\(dp[i ...

  2. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  3. 【AGC 002F】Leftmost Ball

    Description Snuke loves colorful balls. He has a total of N*K balls, K in each of his favorite N col ...

  4. 【agc002f】Leftmost Ball(动态规划)

    [agc002f]Leftmost Ball(动态规划) 题面 atcoder 洛谷 题解 我们从前往后依次把每个颜色按顺序来放,那么如果当前放的是某种颜色的第一个球,那么放的就会变成\(0\)号颜色 ...

  5. AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合

    原文链接https://www.cnblogs.com/zhouzhendong/p/AGC002F.html 题目传送门 - AGC002F 题意 给定 $n,k$ ,表示有 $n\times k$ ...

  6. 2018.10.25 atcoder Leftmost Ball(计数dp+组合数学)

    传送门 dp妙题啊. 我认为DZYODZYODZYO已经说的很好了. 强制规定球的排序方式. 然后就变成了一个求拓扑序数量的问题. 代码: #include<bits/stdc++.h> ...

  7. AtCoder Grand Contest 002 F:Leftmost Ball

    题目传送门:https://agc002.contest.atcoder.jp/tasks/agc002_f 题目翻译 你有\(n*k\)个球,这些球一共有\(n\)种颜色,每种颜色有\(k\)个,然 ...

  8. *AtCoder Grand Contest 002F - Leftmost Ball

    $n \leq 2000,k \leq 2000$,现$n$种球每种有$k$个,在一种排列中,会把每种颜色的球第一个出现的涂成第0种(不同于原来的n种)颜色,问最终会出现多少种不同的序列.膜1e9+7 ...

  9. Atcoder Grand Contest 002 F - Leftmost Ball(dp)

    Atcoder 题面传送门 & 洛谷题面传送门 这道 Cu 的 AGC F 竟然被我自己想出来了!!!((( 首先考虑什么样的序列会被统计入答案.稍微手玩几组数据即可发现,一个颜色序列 \(c ...

随机推荐

  1. python+selenium(环境的安装)

    前言:网上的资料层次不齐,且资料也不全,容易误导新手,所以笔者愿意把你的知识免费分享给大家,笔者用的版本为:python3 此时可能新手就会问了,为什么不用python2呢,因为道理很简单,人要往前走 ...

  2. 微信小程序开发系列四:微信小程序之控制器的初始化逻辑

    微信小程序开发系列教程 微信小程序开发系列一:微信小程序的申请和开发环境的搭建 微信小程序开发系列二:微信小程序的视图设计 微信小程序开发系列三:微信小程序的调试方法 这个教程的前两篇文章,介绍了如何 ...

  3. iview 的 Carousel 走马灯 焦点图 不能用 建议换/vue-awesome-swiper

    https://www.npmjs.com/package/vue-awesome-swiper

  4. mkdir touch vim

    vim和touch都用于新建文件 mkdir用于新建文件夹

  5. Python matlab octave 矩阵运算基础

    基础总结,分别在三种软件下,计算 求逆矩阵 矩阵转置 等运算,比较异同 例子:正规方程法求多元线性回归的最优解 θ=(XTX)-1XTY octave: pwd()当前目录 ones() zeros( ...

  6. Opencascade 选择器算法

    算法的阶段 该算法包括预处理和三个主要阶段. 使用深度优先搜索逐层遍历所有对象 . 预处理 计算平截头体及其主要特征的计算. 第一阶段 - 遍历第一级BVH树 在成功构建选择平截头体之后,算法开始遍历 ...

  7. 批量下载ts视频文件

    第一步 使用chrome 按F12进入开发模式,拖动视频进度条到视频结束: 然后找到.m3u8以结尾的文件并保存为文本文件. 第二步 点开查看里面是否存在如下以ts结尾的文件内容 ...... /20 ...

  8. CPP-基础:inline

    背景: 在C&C++中 一.inline关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义. 表达式形式的宏定义一例: #define ExpressionNam ...

  9. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown error 1146

    问题介绍:   com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown error 1146 MySql语法错误, 但是错 ...

  10. kubeadm1.14.1 安装Metrics Server

    Metrics API 介绍Metrics-Server之前,必须要提一下Metrics API的概念 Metrics API相比于之前的监控采集方式(hepaster)是一种新的思路,官方希望核心指 ...