原文链接https://www.cnblogs.com/zhouzhendong/p/AGC002F.html

题目传送门 - AGC002F

题意

  给定 $n,k$ ,表示有 $n\times k$ 个球,其中,颜色为 $1,2,\cdots, n$ 的球各有 $k$ 个。

  将这些球任意排列成一排,对于每一种颜色,将这种颜色的球的最左边的那个涂成颜色 $0$ 。

  问最终可以得到多少种不同的排列。

  $1\leq n,k\leq 2000,{\rm Mod} = 10^9 +7$

题解

  首先当 $k=1$ 时答案显然是 $1$ ,先判掉。

  然后我们求最终序列中,颜色为 $1,\cdots ,n $ 的球的最左出现位置递增 的方案总数。这样最后只需要把答案乘上 $n!$ 就可以了。

  考虑如何求这个东西。我们考虑动态规划,假装我们一个一个地把颜色涂到序列上。

  令 $dp[i][j]$ 表示已经涂完前 $i$ 种颜色,并已经涂了 $j$ 个颜色 $0$ 的方案总数。

  由于每种颜色的第一个位置都会被涂成 $0$ ,所以当前涂了颜色 $1,\cdots ,i$ 的格子总数为 $(k-1)\times i$ ,再加上被涂成 $0$ 的格子,现在总共已经确定了 $(k-1)\times i+j$ 个格子。而且,显然有 $i\leq j$ 。于是我们来考虑 DP 转移。

  考虑 $dp[i][j]$ 对于其他 DP 值的贡献:

    1. 下一个格子选择涂颜色 $0$ : $dp[i][j+1]+=dp[i][j]$

    2. 让下一个格子成为最终序列中颜色 $i+1$ 第一次出现的地方。显然,我们又占用了 $1$ 个位置;而且除掉变成 $0$ 的和第一个,颜色 $i+1$ 还有 $k-2$ 个没有被填入。相当于在 $k(n-i)-(j-i)-1$ 个格子里面选择 $k-2$ 个,于是转移就是 : $dp[i+1][j]+=\binom{k(n-i)-(j-i)-1}{k-2} dp[i][j]$

  然后就 OK 啦。到这里,您就可以体会到为什么一开始我们要把 $k=1$ 的判掉了吧。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2005,mod=1e9+7;
int n,k;
int Fac[N*N],Inv[N*N],dp[N][N];
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=1LL*x*x%mod)
if (y&1)
ans=1LL*ans*x%mod;
return ans;
}
int C(int n,int m){
if (m<0||m>n)
return 0;
return 1LL*Fac[n]*Inv[m]%mod*Inv[n-m]%mod;
}
int main(){
scanf("%d%d",&n,&k);
if (k==1){
puts("1");
return 0;
}
for (int i=Fac[0]=1;i<=n*k;i++)
Fac[i]=1LL*Fac[i-1]*i%mod;
Inv[n*k]=Pow(Fac[n*k],mod-2);
for (int i=n*k-1;i>=0;i--)
Inv[i]=1LL*Inv[i+1]*(i+1)%mod;
dp[0][0]=1;
for (int i=0;i<=n;i++)
for (int j=i;j<=n;j++){
dp[i][j+1]=(dp[i][j+1]+dp[i][j])%mod;
dp[i+1][j]=(1LL*dp[i][j]*C(k*(n-i)-(j-i)-1,k-2)+dp[i+1][j])%mod;
}
printf("%lld",1LL*dp[n][n]*Fac[n]%mod);
return 0;
}

  

AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合的更多相关文章

  1. AtCoder Grand Contest 002

    AtCoder Grand Contest 002 A - Range Product 翻译 告诉你\(a,b\),求\(\prod_{i=a}^b i\)是正数还是负数还是零. 题解 什么鬼玩意. ...

  2. AtCoder Grand Contest 002 F:Leftmost Ball

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

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

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

  4. [Atcoder Grand Contest 002] Tutorial

    Link: AGC002 传送门 A: …… #include <bits/stdc++.h> using namespace std; int a,b; int main() { sca ...

  5. AGC002 F Leftmost Ball——DP

    题目:https://atcoder.jp/contests/agc002/tasks/agc002_f 充要条件是前缀0的个数 >= 颜色种数. 设计 DP ,放一个颜色的时候就把所有该颜色的 ...

  6. AGC002 F - Leftmost Ball

    貌似哪里讲过这题..总之当时掉线了(理解能力又差水平又低选手的日常).. 看看题目,应该是DP. 尝试了几次换状态,毫无思路.那我们就来继续挖掘性质吧...为了更直观,我们令第i个出现的球颜色就是i( ...

  7. Atcoder Grand Contest 026 (AGC026) F - Manju Game 博弈,动态规划

    原文链接www.cnblogs.com/zhouzhendong/AGC026F.html 前言 太久没有发博客了,前来水一发. 题解 不妨设先手是 A,后手是 B.定义 \(i\) 为奇数时,\(a ...

  8. AtCoder Grand Contest 030 (AGC030) F - Permutation and Minimum 动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/AGC030F.html 草率题解 对于每两个相邻位置,把他们拿出来. 如果这两个相邻位置都有确定的值,那么不管他. 然后把所有的 ...

  9. AtCoder Grand Contest 002题解

    传送门 \(A\) 咕咕 int main(){ cin>>a>>b; if(b<0)puts(((b-a+1)&1)?"Negative": ...

随机推荐

  1. POJ 1659

    题意: 给你一个数列, 判断是否可以构成一个图, 可以则输出 构成图的一种方式 构图根据 Havel-Hakimi定理来构图 (在排序的时候注意 节点下标会变化, 故用结构体) #include< ...

  2. scp命令:远程复制粘贴文件

    文章链接:https://www.cnblogs.com/webnote/p/5877920.html scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有 ...

  3. Oracle的AES加密与解密用法

    Oracle的AES加密与解密用法2013年12月11日 11:50:35 iteye_751 阅读数:428--加密字符串create or replace function des3_enc( i ...

  4. Confluence 6 为登录失败编辑,禁用和配置验证码

    在默认的情况下,验证码将会在失败登录次数达到的时候显示. 如果为登录失败编辑,禁用和配置验证码: 在屏幕的右上角单击 控制台按钮 ,然后选择 General Configuration 链接. 在左侧 ...

  5. Confluence 6 与其他应用整合

    你可以使用 应用链接(Application Links)将 Confluence 与其他应用进行整合.应用链接允许你连接 Confluence 到其他的应用,例如 JIRA 软件或者 JIRA 服务 ...

  6. Exception类的学习与继承总结

    日期:2018.11.11 星期日 博客期:023 Exception类的学习与继承总结 说起来我们上课还是说过的!老师提到了报错问题出现主要分Exception和Error两类!第一次遇见这个问题是 ...

  7. algorithm与numeric的一些常用函数

    numeric中的accumulated的基本用法: 来自:https://blog.csdn.net/u011499425/article/details/52756242 #include < ...

  8. LeetCode(115):不同的子序列

    Hard! 题目描述: 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字 ...

  9. hdu3949 异或空间 + 求矩阵的主元

    给定n个整数,将数分解成01序列,由这n个01序列构成矩阵,这n个数构成线性空间,这就是异或空间 将这个矩阵高斯消元,求出t个主元,那么由着t个主元构成的线性空间里总共有2^t个数 设这t个数分别是a ...

  10. Nginx详解二十二:Nginx深度学习篇之Lua解释器安装及基础语法

    解释器 Lua:Lua是一个简洁.轻量.可扩展的脚本语言 Nginx+Lua优势充分的结合Nginx的并发处理epoll优势的Lua的轻量实现简单的功能切高并发的场景 安装Lua 1.安装解释器:yu ...