[JLOI2015]骗我呢
[JLOI2015]骗我呢
Tags:题解
作业部落
评论地址
TAG:数学,DP
题意
骗你呢
求满足以下条件的\(n*m\)的矩阵的个数对\(10^9+7\)取模
对于矩阵中的第\(i\)行第\(j\)列的元素\(x_{i,j}\)都有
- \(x_{i,j}<x_{i,j+1}\)
- \(x_{i,j}<x_{i-1,j+1}\)
- \(0\le x_{i,j}\le m\)
题解
Part 0 前言
不会做啊!(杠了四五个小时!)
谢两位dalao:blog1、blog2
以下图片均来自于此篇文章:http://www.cnblogs.com/coco-night/p/9552677.html,如有冒犯请与我联系,谢谢!
Part 1 朴素DP
首先发现一个很好的性质:
每行是递增的并且一行\(m\)个元素,取值只能在\([0,m]\)中选
那么必然该行至多有一个位置与后一个位置相差2,其余的都只相差1
由此可以列出一个简单的\(DP\):
\(dp[i][j]\)表示第\(i\)行没有出现过的数是\(j\)的方案数
\(dp[i][j]=\sum_{k=0}^{j+1}dp[i-1][k]\)
至于上界为什么是\(j+1\)可以手动模拟一下,假设这行\(j\)没有出现过,上一行试一试\(j-1\)、\(j\)、\(j+1\)、\(j+2\),发现大于\(j+1\)的就不合法了
略微优化一下就变成了\(dp[i][j]=dp[i-1][j+1]+dp[i][j-1]\)
Part 2 转化为图形
发现这个\(DP\)像极了组合数公式,把它套用在坐标系里就是这个样子

自上而下第\(i\)行,从左往右第\(j\)列的点就表示\(dp[i][j]\),其指向的点就表示可以转移
这样仍然不太好处理,我们继续转化:

还是不好看,给它对称一下:

Part 3 挖掘组合意义
这么一看,不就是从原点出发,只能向右或向上走,不接触直线A,B,到达点(n+m+1,n)的路径条数吗!
直线\(A:y=x+1\),直线\(B:y=x-(m+2)\)
Part 4 计算
这种格路数计算(如两双手)都可以考虑采用容斥计数
不考虑其他限制,原点到\(x,y\)的方案数是\(C_{x+y}^x\)
考虑不合法方案是什么:如依次经过\(AABBAAAABB\)
把它缩一下:\(ABAB\)
可以发现不合法方案要么以\(A\)开头要么以\(B\)开头
表示为首次跨越的直线是\(A\)还是\(B\)
所以:答案=总方案数 - A开头的方案数 - B开头的方案数
\(x=n+m+1,y=n\),把\((x,y)\)沿\(A\)对称得到\((x',y')=(y-1,x+1)\)
每条从\((0,0)\)到\((x',y')\)的路径都依次对应一条以A结尾或者以AB结尾的路径!
如图:(这个图是我自己画的!)

上面是一条以\(A\)结尾的路径

上面是一条以\(AB\)结尾的路径
所以,总共的不合法方案是
- A
- B
- AB
- BA
- ABA
- BAB
- ABAB
- BABA
- ...
为了减去以\(A\)开头的方案,需要减去以A,AB结尾的方案,加上以BA,BAB结尾的方案,减去....
那么实现方式是:把(x,y)沿A翻折,减去答案;将翻折过的点沿B翻着,加上答案;再沿A翻折...
同理计算以\(B\)开头的方案,就是先沿\(B\)折就好了
具体细节的话沿着\(A\)折是\((x,y)->(y-1,x+1)\),沿着\(B\)折是\((x,y)->(y+(m+2),x-(m+2))\)
复杂度是O(n)的,复杂度瓶颈为预处理阶乘,至于计算每次是像跳棋一样,复杂度为\(O(logn)\)
完美解决本题!
代码
#include<iostream>
using namespace std;
const int P=1e9+7,N=3e6+10;
int n,m,up,inv[N],jc[N],inj[N];
int Calc(int x,int y) {return (x<0||y<0)?0:1ll*jc[x+y]*inj[x]%P*inj[y]%P;}
void flip1(int &x,int &y) {swap(x,y);x--;y++;}
void flip2(int &x,int &y) {swap(x,y);x+=m+2;y-=m+2;}
void add(int &x,int y) {x+=y;if(x>=P) x-=P;}
int main()
{
cin>>n>>m;inv[0]=inv[1]=jc[0]=inj[0]=1;up=max(n,m)*3+1;
for(int i=2;i<=up;i++) inv[i]=(P-1ll*P/i*inv[P%i]%P)%P;
for(int i=1;i<=up;i++) jc[i]=1ll*jc[i-1]*i%P,inj[i]=1ll*inj[i-1]*inv[i]%P;
int x=n+m+1,y=n,ans=Calc(x,y);
while(x>=0&&y>=0)
{
flip1(x,y);add(ans,P-Calc(x,y));
flip2(x,y);add(ans,Calc(x,y));
}
x=n+m+1,y=n;
while(x>=0&&y>=0)
{
flip2(x,y);add(ans,P-Calc(x,y));
flip1(x,y);add(ans,Calc(x,y));
}
return cout<<ans<<endl,0;
}
[JLOI2015]骗我呢的更多相关文章
- 【BZOJ4005】[JLOI2015] 骗我呢(容斥,组合计数)
[BZOJ4005][JLOI2015] 骗我呢(容斥,组合计数) 题面 BZOJ 洛谷 题解 lalaxu #include<iostream> using namespace std; ...
- 【BZOJ4005】[JLOI2015]骗我呢
题意: Alice和Bob在经过了数学的洗礼之后,不再喜欢玩对抗游戏了,他们喜欢玩合作游戏.现在他们有一个n×m的网格,Alice和Bob要在一定规则下往网 格里填数字,Alice和Bob都是聪明绝顶 ...
- bzoj4005[JLOI2015]骗我呢
http://www.lydsy.com/JudgeOnline/problem.php?id=4005 神题~远距离orz 膜拜PoPoQQQ大神 #include<cstdio> #i ...
- [BZOJ4005][JLOI2015]骗我呢-[dp+容斥]
Description 传送门 Solution 如果单独考虑一行i,则左边位置的数严格比右边位置的数小.而一行有m个位置,它们可以填[0,m]这m+1个数,则必然有一个数不存在. 定义第i行的第j位 ...
- 洛谷 P3266 - [JLOI2015]骗我呢(容斥原理+组合数学)
题面传送门 神仙题. 首先乍一看此题非常棘手,不过注意到有一个条件 \(0\le x_{i,j}\le m\),而整个矩阵恰好有 \(m\) 列,这就启发我们考虑将每个元素的上下界求出来,如果我们第一 ...
- 「JLOI2015」骗我呢 解题报告?
「JLOI2015」骗我呢 这什么神仙题 \[\color{purple}{Link}\] 可以学到的东西 对越过直线的东西翻折进行容斥 之类的..吧? Code: #include <cstd ...
- 【LOJ】#2109. 「JLOI2015」骗我呢
题解 我深思熟虑许久才算是明白个大概的计数问题吧 先是转化成一个矩形,列一条直线y = x,y = x - (m + 1)我们从(0,0)走到(n + m + 1,m + 1)就是答案 因为我们起始相 ...
- BZOJ 4005 [JLOI 2015] 骗我呢
首先,我们可以得到:每一行的数都是互不相同的,所以每一行都会有且仅有一个在 $[0, m]$ 的数没有出现. 我们可以考虑设 $Dp[i][j]$ 为处理完倒数 $i$ 行,倒数第 $i$ 行缺的数字 ...
- [JLOI 2015]骗我呢
传送门 Description 求给\(n*m\)的矩阵填数的方案数 满足: \[ 1\leq x_{i,j}\leq m \] \[ x_{i,j}<x_{i,j+1} \] \[ x_{i, ...
随机推荐
- 如何打通CMDB,实现就近访问
CMDB在企业中,一般用于存放与机器设备.应用.服务等相关的元数据.当企业的机器及应用达到一定规模后就需要这样一个系统来存储和管理它们的元数据.有一些广泛使用的属性,例如机器的IP.主机名.机房.应用 ...
- 权限管理系统之项目框架搭建并集成日志、mybatis和分页
前一篇博客中使用LayUI实现了列表页面和编辑页面的显示交互,但列表页面table渲染的数据是固定数据,本篇博客主要是将固定数据变成数据库数据. 一.项目框架 首先要解决的是项目框架问题,搭建什么样的 ...
- 第32章 事件 - Identity Server 4 中文文档(v1.0.0)
日志记录是更低级别的"printf"样式 - 事件代表有关IdentityServer中某些操作的更高级别信息.事件是结构化数据,包括事件ID,成功/失败信息,类别和详细信息.这使 ...
- [MySQL] mysql 的读写锁与并发控制
1.无论何时只要有多个查询在同一时刻修改数据,都会产生并发控制的问题 2.讨论mysql在两个层面,服务器层和存储引擎层,如何并发控制读写 3.举了个mbox邮箱文件的例子,说如果有多个进程同时对mb ...
- xdebug配置
[XDebug] ;指定性能分析文件的存放目录 xdebug.profiler_output_dir="D:\phpStudy\tmp\xdebug" xdebug.trace_o ...
- Java开发笔记(三十三)字符包装类型
正如整型int有对应的包装整型Integer那样,字符型char也有对应的包装字符型Character.初始化字符包装变量也有三种方式,分别是:直接用等号赋值.调用包装类型的valueOf方法.使用关 ...
- OO_BLOG1_简单表达式求导问题总结
作业1-1 包含简单幂函数的多项式导函数的求解 I. 基于度量的程序结构分析 1)程序结构与基本度量统计图 2)分析 本人的第一次作业的程序实现逻辑十分简单,但是OOP的色彩并不强烈,程序耦合度过 ...
- C#获得指定目录床架时间、更新时间和最后访问时间等信息的代码
将做工程过程常用的内容片段备份一次,下面的内容内容是关于C#获得指定目录床架时间.更新时间和最后访问时间等信息的内容,希望能对小伙伴们也有用. using System;using System.IO ...
- AndroidStudio开发Java工程(解决java控制台中文打印乱码+导入jar包运行工程)
这篇分享一点个人AS开发java工程经验,虽然有时候还是得打开eclipse来运行java项目,但能用AS的时候还是尽量用AS,毕竟一个字,爽~ 废话不多说,进入正题. 一.开发Java工程 你有两种 ...
- Delphi中打开网页连接的几种方法
https://blog.csdn.net/zisongjia/article/details/69398143 正好要用,做个记录.Mark下. 使用了第一种 uses shellapi proce ...