[BZOJ4005][JLOI2015]骗我呢-[dp+容斥]
Description
Solution
如果单独考虑一行i,则左边位置的数严格比右边位置的数小。而一行有m个位置,它们可以填[0,m]这m+1个数,则必然有一个数不存在。
定义第i行的第j位突变需要满足$x[i][j+1]-x[i][j]>1$,此时不存在的数为j。
通过分析可以得到,假如在i-1行的突变位置为j+1,则第i行突变位置的合法范围为[j,m]。*
设f[i][j]为在第i行,突变位置为j的情况数。
则递推式为:$f[i][j]=f[i-1][j+1]+f[i][j-1]$。
因为当第i-1行在第j+1位突变,第i行的突变位置即为j。f[i][j-1]为在[0,j-1]位突变的情况数,由*可得知这些情况也同样可以在第j位突变。
特殊的,$f[i][0]=f[i-1][0]+f[i-1][1]$,$f[i][m]=f[i][m-1]$。

如图,我们把转移画出来后将第i行往右移i-1格并建立虚拟节点来满足f[i][0]的转移。
图中的n=3,m=3。
此时的点(n,n+m+1)[即为第n行第n+m个点]表示的并不是所有情况之和,而是第n行突变位置为m的情况数。
我们考虑多加一行一列,根据递推式,点(n+1,n+m+2)即为第n行所有情况之和了。
最后将得到图形补全为矩形后是会有n+1行n+m+2列。
将该图画在平面直角坐标系里(即将其翻转),则终点坐标为(n,n+m+1)

如图,直线ya=x+1和直线yb=x-(m+2)即为边界。
我们把多次越过同一边界视为只越过一次。则越界方案为ababa...或babab...。
则ans=总方案数-第一次越过a的次数-第一次越过b的次数。
对于先越过a的,考虑:-越界方案末尾为a的情况数+越界方案末尾为ba的方案数-越界方案末尾为aba的方案数。。。直到方案数为0。
对于越界方案末尾为a的情况数,为将整个图针对直线a翻转后(1,1)到对称终点的方案;当越界方案末尾为ba,则在上一个图的基础上把图沿着直线b翻转,计算(1,1)到本次到对称终点的方案数。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod=1e9+;
int n,m;
ll fac[],inv[];
void pre()
{
fac[]=inv[]=;
fac[]=inv[]=;
for (int i=;i<=;i++)
{
fac[i]=fac[i-]*i%mod;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
for (int i=;i<=;i++) inv[i]=inv[i]*inv[i-]%mod;
}
ll C(int x,int y)
{
if (x<y||x<||y<) return ;
return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
ll cal(int x,int y)
{
if (x<||y<) return ;return C(x+y,y);
}
void turnA(int &x,int &y)
{
swap(x,y);
x--;y++;
}
void turnB(int &x,int &y)
{
swap(x,y);x+=m+;y-=m+;
}
ll ans;
int main()
{
scanf("%d%d",&n,&m);
pre();
ans=cal(n+m+,n);
int x=n+m+,y=n;
while (x>=&&y>=)
{
turnA(x,y);ans=(ans-cal(x,y))%mod;
turnB(x,y);ans=(ans+cal(x,y))%mod;
}
x=n+m+,y=n;
while (x>=&&y>=)
{
turnB(x,y);ans=(ans-cal(x,y))%mod;
turnA(x,y);ans=(ans+cal(x,y))%mod;
}
if (ans<) ans+=mod;
cout<<ans;
}
[BZOJ4005][JLOI2015]骗我呢-[dp+容斥]的更多相关文章
- 【BZOJ4005】[JLOI2015] 骗我呢(容斥,组合计数)
[BZOJ4005][JLOI2015] 骗我呢(容斥,组合计数) 题面 BZOJ 洛谷 题解 lalaxu #include<iostream> using namespace std; ...
- bzoj4005[JLOI2015]骗我呢
http://www.lydsy.com/JudgeOnline/problem.php?id=4005 神题~远距离orz 膜拜PoPoQQQ大神 #include<cstdio> #i ...
- [JLOI2015]骗我呢
[JLOI2015]骗我呢 Tags:题解 作业部落 评论地址 TAG:数学,DP 题意 骗你呢 求满足以下条件的\(n*m\)的矩阵的个数对\(10^9+7\)取模 对于矩阵中的第\(i\)行第\( ...
- bzoj 3622 DP + 容斥
LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...
- 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)
4665: 小w的喜糖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 94 Solved: 53 Description 废话不多说,反正小w要发喜 ...
- [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥
题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...
- HDU 5838 (状压DP+容斥)
Problem Mountain 题目大意 给定一张n*m的地图,由 . 和 X 组成.要求给每个点一个1~n*m的数字(每个点不同),使得编号为X的点小于其周围的点,编号为.的点至少大于一个其周围的 ...
- Codeforces 611C New Year and Domino DP+容斥
"#"代表不能放骨牌的地方,"."是可以放 500*500的矩阵,q次询问 开两个dp数组,a,b,a统计横着放的方案数,b表示竖着放,然后询问时O(1)的,容 ...
- [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】
题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案 ...
随机推荐
- Elasticsearch alias别名管理小结
Elasticsearch alias别名管理小结 By:授客 QQ:1033553122 建创测试数据 1 创建别名 2 移除别名 3 创建测试数据 4 批量操作 5 例1. 5 例2. 把多个索引 ...
- python语言学习---4
第五天 1.任意个参数函数怎么敲? 只需定义一个可变参数即可:可变参数名字前要加 * ,可以传入0个或多个参数. #内部解释器原理:Python解释器会把传入的一组参数组装成一个tuple(不可变)传 ...
- git 入门教程之变基合并
git 鼓励大量使用分支---"早建分支!多用分支!",这是因为即便创建再多的分支也不会造成存储或内存开销,并且分支的作用有助于我们分解逻辑工作,这样一样其实比维护单一臃肿分支要简 ...
- matlab练习程序(神经网络分类)
注:这里的练习鉴于当时理解不完全,可能会有些错误,关于神经网络的实践可以参考我的这篇博文 这里的代码只是简单的练习,不涉及代码优化,也不涉及神经网络优化,所以我用了最能体现原理的方式来写的代码. 激活 ...
- mysql练习----More JOIN operations
This tutorial introduces the notion of a join. The database consists of three tables movie , actor a ...
- Oracle完全复制表结构的存储过程
最近在处理一个分表的问题时,需要为程序创建一个自动分表的存储过程,需要保证所有表结构,约束,索引等等一致,此外视图,存储过程,权限等等问题暂不用考虑. 在Mysql中,创建分表的存储过程,相当简单:c ...
- 利用系统函数模拟实现nginx 系统脚本启动的特殊颜色专业效果
利用系统函数模拟实现nginx 系统脚本启动的特殊颜色专业效果/etc/init.d/nginxd {start/stop/restart/reload}利用if语句实现: ============= ...
- 利用fpm制作rpm包
使用fpm制作rpm包 安装如下 [root@web01 ~]# yum install -y gcc zlib zlib-devel wget http://ruby.taobao.org/mirr ...
- 记录参加QCon2017北京站的心得
如有侵权,请告知作者删除.scottzg@126.com 很荣幸参加QCon全球软件开发大会,这里特别感谢我们部门的总经理,也是<互联网广告算法和系统实践>此书的作者王勇睿.因为他我才有这 ...
- #005Python实验楼基本操作学习笔记
Ctrl + D 输入一个 EOF 字符来退出解释器,也可以键入 exit() 来退出解释器. 打开 Xfce 终端,键入 vim helloworld.py 来启动 Vim 并编辑 hellowor ...