【BZOJ】4767: 两双手【组合数学】【容斥】【DP】
4767: 两双手
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 1057 Solved: 318
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
0 1 1 0
2 3
Sample Output
Solution
看起来很像一般的网格图求路径数,在没有障碍物的情况下,处理出到达终点分别用两种步数走的步数(解方程唯一固定,再用组合数学,方案数就等于$C(x+y,x)$,$x$和$y$分别是两种步数的次数。
可是这道题有障碍格。
所以在上述基础上进行容斥DP即可。将能走到的所有障碍点的$x$和$y$(从原点出发)预处理出来,(将终点的$x$、$y$值也放入结构体)排序后,后面的DP值要容斥减去前面能到达它的方案数。最后答案就是$dp[n]$。(因为一开始保证了结构体里所有障碍点都比目标点要小)
【注意】预处理阶乘的逆元线性从后往前线性求得,不然会TLE!
Code
#include<bits/stdc++.h>
#define mod 1000000007
#define LL long long
using namespace std; int Ax, Ay, Bx, By, n, Ex, Ey; struct Node {
int x, y;
} QAQ[];
bool cmp(Node a, Node b) { if(a.x == b.x) return a.y < b.y; return a.x < b.x; } LL mpow(LL a, LL b) {
LL ans = ;
for(; b; b >>= , a = a * a % mod)
if(b & ) ans = ans * a % mod;
return ans;
} void cal(int &x, int &y) {////解方程计算两种步数
LL a1, a2, b1, b2;
b1 = y * Ax - x * Ay, b2 = Ax * By - Ay * Bx;
a1 = x * By - y * Bx, a2 = Ax * By - Ay * Bx;
if(a2 == || b2 == ) { x = -, y = -; return ; }
if((a1 / a2) * a2 != a1 || (b1 / b2) * b2 != b1) { x = -, y = -; return ; }
x = a1 / a2, y = b1 / b2;
} LL fac[], inv[];
LL C(LL a, LL b) {
if(a < b) return ;
return fac[a] * inv[a-b] % mod * inv[b] % mod;
} void init() {
fac[] = ;
for(int i = ; i <= ; i ++)
fac[i] = fac[i-] * i % mod;
inv[] = ; inv[] = mpow(fac[], mod - );
for(int i = ; i >= ; i --)
inv[i] = inv[i + ] * (i + ) % mod;////线性求阶乘逆元
} LL f[];
int main() {
scanf("%d%d%d", &Ex, &Ey, &n);
scanf("%d%d%d%d", &Ax, &Ay, &Bx, &By);
cal(Ex, Ey);
for(int i = ; i <= n; i ++) {
scanf("%d%d", &QAQ[i].x, &QAQ[i].y);
cal(QAQ[i].x, QAQ[i].y);
if(QAQ[i].x < || QAQ[i].y < || QAQ[i].x > Ex || QAQ[i].y > Ey) {/////不合法的步数筛掉
n --; i --;
}
}
QAQ[++n].x = Ex, QAQ[n].y = Ey;
sort(QAQ + , QAQ + + n, cmp); init(); for(int i = ; i <= n; i ++) {
f[i] = C(QAQ[i].x + QAQ[i].y, QAQ[i].x);
if(f[i] == ) continue;
for(int j = ; j < i; j ++) {
f[i] -= (f[j] * C(QAQ[i].x - QAQ[j].x + QAQ[i].y - QAQ[j].y, QAQ[i].x - QAQ[j].x)) % mod;/////容斥
f[i] = (f[i] % mod + mod) % mod;
}
}
printf("%lld", f[n]);
return ;
}
【BZOJ】4767: 两双手【组合数学】【容斥】【DP】的更多相关文章
- BZOJ.4767.两双手(组合 容斥 DP)
题目链接 \(Description\) 棋盘上\((0,0)\)处有一个棋子.棋子只有两种走法,分别对应向量\((A_x,A_y),(B_x,B_y)\).同时棋盘上有\(n\)个障碍点\((x_i ...
- bzoj 4767: 两双手 组合 容斥
题目链接 bzoj4767: 两双手 题解 不共线向量构成一组基底 对于每个点\((X,Y)\)构成的向量拆分 也就是对于方程组 $Ax * x + Bx * y = X $ \(Ay * x + B ...
- 2019.02.11 bzoj4767: 两双手(组合数学+容斥dp)
传送门 题意简述:你要从(0,0)(0,0)(0,0)走到(ex,ey)(ex,ey)(ex,ey),每次可以从(x,y)(x,y)(x,y)走到(x+ax,y+ay)(x+ax,y+ay)(x+ax ...
- bzoj 4767 两双手 - 动态规划 - 容斥原理
题目传送门 传送门I 传送门II 题目大意 一个无限大的棋盘上有一只马,设马在某个时刻的位置为$(x, y)$, 每次移动可以将马移动到$(x + A_x, y + A_y)$或者$(x + B_x, ...
- BZOJ 4767 两双手
题解: 发现这种题目虽然可以想出来,但磕磕碰碰得想挺久的 根据数学可以知道组成方案是唯一的(集合) 然后发现每个使用的大小可能是接近n^2的 直接dp(n^4)是过不了的 那么先观察观察 我们可以把每 ...
- BZOJ 4767: 两双手 [DP 组合数]
传送门 题意: 给你平面上两个向量,走到指定点,一些点不能经过,求方案数 煞笔提一开始被题面带偏了一直郁闷为什么方案不是无限 现在精简的题意.....不就是$bzoj3782$原题嘛,还不需要$Luc ...
- HDU 5794 A Simple Chess (容斥+DP+Lucas)
A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...
- [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
随机推荐
- 关于项目中根据当前数据库中最大ID生成下一个ID问题——(五)
1.关于部门管理时候根据上级产生下级部门ID的问题(传入一个参数是上级部门id)
- XXX变种-防火墙放行自身
1.利用防火墙命令放行自身手法 netsh firewall add allowedprogram "C:\Users\USER\AppData\Local\Temp\Discord Can ...
- Serv-U 的升级及数据备份和迁移【转】
Serv-U 配置备份 在serv-u7.x及以上版本安装目录下,有一个文件Serv-U.Archive是serv-u的配置文件,有一个users文件夹是Serv-U的域和用户的信息,那么我们只需 ...
- Python缓存技术,装x新高度。
一段非常简单代码 普通调用方式 def console1(a, b): print("进入函数") return (a, b) print(console1(3, 'a')) pr ...
- 为什么我们不要.NET程序员(读后有点想法,所以转来了) 注:本文来自CSDN
也许你已经知道了,我们正在招聘最优秀的程序员.不错,每个人都这样说.但是我们的程序员能打败你们的——任何时候.比如,米奇虽然只有5英尺高,但他是一个有相当实力的击剑手.维托尔德以前是一个6’3″的职业 ...
- C++如何判断大小端
http://bbs.chinaunix.net/thread-1257205-1-1.html #include <stdio.h>#include <string.h>#i ...
- php内存管理机制与垃圾回收机制
PHP内存管理机制 1 var_dump(memory_get_usage()); //获取内存 2 $a = "laruence"; //定义一个变量 3 var_dump(me ...
- UVA10212 【The Last Non-zero Digit.】
暴力可做!!!(十秒还不打暴力!!!)暴力算阶乘边算边取余上代码 #include<iostream> #define int long long //开long long using n ...
- 在VirtualBox虚拟机中安装Centos操作系统怎么与本地XShell远程连接
问题: 在VirtualBox安装好了CentOS操作系统后,我们怎么才可以用XSell连接虚拟机中的CentOS呢? 答案: (1)在windows下用cmd--ipconfig查看VirtualB ...
- Zabbix监控实例
本节内容: zabbix web添加主机 定义Items 创建graph 创建template 一.zabbix web添加主机 1. 进入zabbix web界面,点击配置—>主机—>创 ...