题解 SP19148【INS14G - Kill them All】
SP19148【INS14G - Kill them All】
感觉其他博客讲的不是很清楚,也没有说组合数公式是怎么来的,我这样数论极菜的萌新看了好久才想明白qwq。。
还是先给出本题组合数公式C(n-1,n/2)
分析一
转化成坐标系上的移动方案问题
把第一个人杀的怪物看成横坐标,第二个人的看成纵坐标,怪物由第一个人杀向右走,反之向上走。
可知第一步一定向右,枚举终点的纵坐标m(即向上的步数),题目就变成从点(1,0)开始走到(n-m,m)不越过y=x的方案数。枚举向上步数m,总方案数为C(n-1,m)(n-1步中选m步),现在我们要减去非法方案数。
从(1,0)走到(n-m,m)的不合法方案按y=x翻转后与从(0,1)走到(n-m,m)的方案相对应
注意这里的翻转,终点是不翻转的,只翻转起点。
不合法方案为\(C_{n-1}^{m-1}\)(n-1步中向上走了m-1步),由此可知答案为\(C_{n-1}^m-C_{n-1}^{m-1}\)
公式(用i枚举终点纵坐标,0步没有不合法方案特判,0≤m(第二个人杀的次数)≤n/2):
\(C_{n-1}^0+\sum\limits_{i=1}^{\left\lfloor\frac{n}{2}\right\rfloor}(C_{n-1}^{i}-C_{n-1}^{i-1})=\sum\limits_{i=1}^{\left\lfloor\frac{n}{2}\right\rfloor}C_{n-1}^i-\sum\limits_{i=1}^{\left\lfloor\frac{n}{2}\right\rfloor-1}C_{n-1}^{i}=C_{n-1}^{\left\lfloor\frac{n}{2}\right\rfloor}\)(公式来自@Alpha)
得组合数公式C(n-1,n/2)
(感谢@Alpha提供的图例与分析!)
分析二
建议可以先看看关于卡特兰数的博客中对卡特兰数的应用,和这题很像,便于理解
把题目放到笛卡尔坐标系(平面直角坐标系)中考虑(如图1),x轴表示每个怪兽,从原点出发向右上方走表示由D杀了,向右下方走表示由S杀了。相当于我从原点出发,我的轨迹不能在过程中碰到x轴。
图1

可知第一步一定向上,所以原题转化为从原点出发,轨迹在过程中不能跑到x轴下面。
枚举向上步数m,总方案数为C(n-1,m),现在我们要减去非法方案数。对于非法的轨迹,有两种翻转方式:
把它第一次碰到y=-1前的轨迹按y=-1翻转(见P1641 [SCOI2010]生成字符串),也就是从(0,-2)到达原先的终点的方案与不合法方案一一对应,会发现向上走的步数比翻转前多1,即得C(n,m+1)
把它第一次碰到y=-1后的轨迹按y=-1翻转(如图2),在n,m确定的情况下,终点是确定的,翻转后的轨迹和原轨迹的方案一一对应。那么终点在哪里呢? 设p为翻转后终点纵坐标,m为翻转前的向上步数,则有m - (n - m) + p = -2 (n-m为向下走的步数,翻转前终点纵坐标+1=翻转后纵坐标的相反数-1)-> p = -2 + n - 2m ,设当向上走x步时可以到达p,则 x - (n - x) = -2 + n - 2m -> x = n - m - 1,由于翻转后的轨迹和原轨迹的方案一一对应,所以到达p的方案数就是不合法的方案数
所以非法方案数为C(n,n-m-1)=C(n,m+1),(见组合数中的互补性质,即从m个不同元素中取出n个元素的组合数=从m个不同元素中取出(m-n)个元素的组合数)
枚举向上步数为m,总方案数为C(n,m)-C(n,m+1);
公式(n已减1,n-1步没有不合法方案特判,n/2≤m(第一个人杀的次数)≤n-1):
\(C_{n-1}^{n-1}+\sum\limits_{i=\left\lfloor\frac{n}{2}\right\rfloor}^{n-2}(C_{n-1}^{i}-C_{n-1}^{i+1})=\sum\limits_{i=\left\lfloor\frac{n}{2}\right\rfloor}^{n-1}C_{n-1}^i-\sum\limits_{i=\left\lfloor\frac{n}{2}\right\rfloor+1}^{n-1}C_{n-1}^{i}=C_{n-1}^{\left\lfloor\frac{n}{2}\right\rfloor}\)(公式来自@Alpha)
答案为C(n-1,n/2)
图2

(以上思路由这个博客改进而来)
代码1
fac[i]存1~i的阶乘
inv[i]存1~i逆元的乘积
#include<cstdio>
using namespace std;
#define p 1000000007
long long fac[1000005],inv[1000005];
inline long long C(int n,int m) {
if (n==m || m==0) return 1;
return fac[n]*inv[m]%p*inv[n-m]%p;
}
int main() {
int T,n;
scanf("%d",&T),fac[0]=inv[0]=inv[1]=1;
for (int i=1; i<1000005; i++) fac[i]=fac[i-1]*i%p;
for (int i=2; i<1000005; i++) inv[i]=p-(p/i)*inv[p%i]%p;
for (int i=2; i<1000005; i++) inv[i]=inv[i-1]*inv[i]%p;
while(T--)
scanf("%d",&n),printf("%lld\n",C(n-1,n/2));
}
代码2
#include<cstdio>
using namespace std;
#define p 1000000007
#define int long long
int fac[1000005];
inline int pow(int x) {
int ans=1;
x%=p;
for (int i=p-2; i; i>>=1,x=x*x%p)
if (i&1) ans=ans*x%p;
return ans;
}//快速幂求逆元(x^(p-2))
signed main() {
int T,n;
scanf("%lld",&T),fac[0]=1;
for (int i=1; i<=1000005; i++) fac[i]=fac[i-1]*i%p;
while(T--)
scanf("%lld",&n),printf("%lld\n", fac[n-1]*pow(fac[n/2]*fac[n-1-n/2]%p)%p);
}
通过这题的确对组合数的应用加深了不少,如果分析有误还望指出qwq!
参考文章:
最后再次感谢@Alpha的耐心讲解与图例公式_
题解 SP19148【INS14G - Kill them All】的更多相关文章
- 「题解」:Kill
问题 A: Kill 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...
- CSP-S 模拟测试 45 题解
由于咕掉的题解太多了,所以只能趁改完不动题的时间,来补补坑qwq,还是太弱了. 考试过程: 到新机房的第一次考试,貌似海星? 第一题一开始就觉得是个贪心,但以为所有小怪兽都要打完,所以想复杂了,但后来 ...
- 2014年亚洲区域赛北京赛区现场赛A,D,H,I,K题解(hdu5112,5115,5119,5220,5122)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 下午在HDU上打了一下今年北京区域赛的重现,过了5题,看来单挑只能拿拿铜牌,呜呜. ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
- LeetCode Kill Process
原题链接在这里:https://leetcode.com/problems/kill-process/description/ 题目: Given n processes, each process ...
- Leetcode 简略题解 - 共567题
Leetcode 简略题解 - 共567题 写在开头:我作为一个老实人,一向非常反感骗赞.收智商税两种行为.前几天看到不止两三位用户说自己辛苦写了干货,结果收藏数是点赞数的三倍有余,感觉自己的 ...
- [CSP-S模拟测试97]题解
A.小盆友的游戏 感觉题解解释的很牵强啊……还是打表找规律比较靠谱 对于每个人,它构造了一个期望函数$f(x)$,设它的跟班个数为$cnt[x]$,那么令$f(x)=2^{cnt[x]}-1$(??鬼 ...
- [CSP-S模拟测试45]题解
开局一行$srand$,得分全靠随机化. A.kill 发现两个并不显然的性质: 1.选中的人和怪物一定是按顺序的.第一个人打所有被选中怪物的第一只,第二个人打第二只,$etc$. 2.最优方案打的怪 ...
- ORACLE快速彻底Kill掉的会话
在ORACLE数据库当中,有时候会使用ALTER SYSTEM KILL SESSION 'sid,serial#'杀掉一个会话进程,但是使用这个SQL语句杀掉会话后,数据库并不会立即释放掉相关的资源 ...
随机推荐
- JS高级---案例:验证表单
案例:验证表单 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- yii2验证规则
验证规则 1.内置验证规则 [['sex', 'partner_id'], 'integer'], [['partner_id', 'camp_id',], 'required'], [['creat ...
- 与大神聊天1h
与大神聊天1h 啊,与大神聊天1h真的是干货满满 解bug问题 之所以老出bug是因为我老是调用别人的包啊,在调参数的时候,并不知道内部机制 其实就自己写一个函数,然后能把功能实现就好了. 问题是,出 ...
- 部署Discuz和wordoress
安装discuz 直接把安装包拷贝到根目录下 然后在浏览器中输入http://localhost/myweb/install/index.php 打开安装向导界面,需要修改一下myweb的权限 安全属 ...
- 10.pandas的替换和部分替换(replace)
在处理数据的时候,很多时候会遇到批量替换的情况,如果一个一个去修改效率过低,也容易出错.replace()是很好的方法. 源数据 1.替换全部或者某一行 replace的基本结构是:df.repl ...
- python3爬虫(4)各种网站视频下载方法
python3爬虫(4)各种网站视频下载方法原创H-KING 最后发布于2019-01-09 11:06:23 阅读数 13608 收藏展开理论上来讲只要是网上(浏览器)能看到图片,音频,视频,都能够 ...
- java简单学生成绩管理系统
题目要求: 一. 数据结构要求:(5 分) 1.定义 ScoreInformation 类,其中包括七个私有变量(stunumber, name, mathematicsscore, englishi ...
- 搭建Python开发环境(Mac)
准备 Python官网: https://www.python.org/ Python官方文档: https://docs.python.org/ 环境搭建 简介 pipenv是Python官方推荐的 ...
- MySQL加号+ 的作用
案例:查询员工名和员工姓,连接成一个字段,并显示为: 姓名 SELECT last_name+first_name AS 姓名 FROM employees;没有报错但姓名一下全是0 Java中的 + ...
- 第五十四篇 Linux相关——远程连接SSH
No.1. SSH(Secure Shell)安全外壳协议 建立在应用层基础上的安全协议 可靠,专为远程登录会话和其他网络服务提供安全性的协议 有效防止远程管理过程中的信息泄漏问题 SSH客户 ...