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. Javaweb学习笔记10—文件上传与下载

    今天来讲javaweb的第10阶段学习.文件的上传与下载,今天主要说的是这个功能的实现,不用说了,听名字就是外行人也知道肯定很重要啦. 老规矩,首先先用一张思维导图来展现今天的博客内容.       ...

  2. ie 导出不行,不兼容问题,或只出现后缀文件无法识别

    // 下载模板 @RequestMapping("/download") @ResponseBody public ResponseEntity<byte[]> dow ...

  3. 洛谷 P2604 [ZJOI2010]网络扩容

    题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. 将1到N的最大流增加K所需的最小扩容费用. ...

  4. (转)编码剖析Spring管理Bean的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52832434 在Spring的第一个案例中,我们已经知道了怎么将bean交给Spring容器进 ...

  5. js 逻辑运算符、等号运算符

    1 逻辑运算符 逻辑运算只有2个结果,一个为true,一个为false. 1.且&& ★ 两个表达式为true的时候,结果为true. ------------------------ ...

  6. VBA Promming入门教程——变量的使用

    数据类型 VBA中的数据类型可分为两种 示例 String Sub Main Dim s as string s = "Hello" msgbox(s) End Sub Singl ...

  7. 优先队列 || POJ 1442 Black Box

    给n个数,依次按顺序插入,第二行m个数,a[i]=b表示在第b次插入后输出第i小的数 *解法:写两个优先队列,q1里由大到小排,q2由小到大排,保持q2中有i-1个元素,那么第i小的元素就是q2的to ...

  8. 服务器禁用ping

    linux禁ping.这里操作的是centos6.5内核参数禁ping禁用ping #echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all启用ping ...

  9. 如何在windows 2008 IIS7 上实现AD域的访问控制

    1.服务器加入域 2.创建点站 3.对站站进行设置 3.1设置网站的连接模式 选中站点,在控制台右侧 选择 基本设置 => 选择 应用程序用户 3.2 开启访问模式 选择站点 => 身份验 ...

  10. Java开发者写SQL时常犯的10个错误

        首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 我要投稿 更多频道 » - 导航条 - 首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 我要投稿 更多频道 » - iOS ...