Codeforces559C Gerald and Giant Chess
一道计数类\(DP\)
原题链接
我们可以先计算从左上角到右下角总的路径,再减去经过黑色方格的路径即是答案。
总路径数可以用组合数直接计算:\(C_{H+W-2}^{H-1}\)
因为从左上角到右下角必须走\(H+W-2\)步,而其中必须向右走\(H-1\)步,向下走\(W-1\)步,所以这就相当于是从\(H+W-2\)步中取出\(H-1\)步来向右走,剩下的向下走,这就是一个排列组合问题。
然后先按\(x,y\)递增的顺序对黑色方块进行排序,并设右下角为第\(n+1\)个黑色方块,第\(i\)个方块坐标为\((x_i,y_i)\)。
定义\(f[i]\)表示从左上角走到第\(i\)个黑色方块,且途中不经过其他黑色方块的路径总数。
于是有状态转移方程:
\(\qquad\qquad f[i]=C_{x_i+y_i-2}^{x_i-1}-\sum\limits_{j=1}^{i-1}f[j]\times C_{x_i-x_j+y_i-y_j}^{x_i-x_j},\text{且}x_i\geqslant x_j,y_i\geqslant y_j\)
其中第一个组合数是求从左上角到第\(i\)个黑色方块总的路径数,而这就需要减去这些路径中经过黑色方块的路径数,\(f[j]\)是从左上角到第\(j\)个黑色方块,且途中不经过其他黑色方块的路径数,而后面的组合数即是求从第\(j\)个黑色方块到第\(i\)个黑色方块的总路径数,两者满足乘法原理,乘起来就是从左上角到第\(i\)个黑色方块的路径中经过第\(j\)个黑色方格的路径数,而因为在\(j\)循环的过程中保证了第一个经过的黑色方格不同,所以计数时不会重复,直接累加减去即可。
最后组合数的计算可以先预处理阶乘和对应的逆元来\(O(1)\)计算。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int M = 2010;
const int mod = 1e9 + 7;
struct dd {
int x, y;
};
dd a[M];
int f[M];
ll inv[N << 1], fac[N << 1];
int re()
{
int x = 0;
char c = getchar();
bool p = 0;
for (; c<'0' || c>'9'; c = getchar())
p = (c == '-' || p) ? 1 : 0;
for (; c >= '0'&&c <= '9'; c = getchar())
x = x * 10 + (c - '0');
return p ? -x : x;
}
int comp(dd x, dd y)
{
if (x.x == y.x)
return x.y < y.y;
return x.x < y.x;
}
int ksm(int x, int y)
{
int s = 1;
for (; y; y >>= 1, x = 1LL * x*x%mod)
if (y & 1)
s = 1LL * s*x%mod;
return s;
}
int C(int x, int y)
{
return fac[y] * inv[x] % mod*inv[y - x] % mod;
}
int main()
{
int i, j, h, w, n, o;
h = re();
w = re();
n = re();
for (i = 1; i <= n; i++)
{
a[i].x = re();
a[i].y = re();
}
sort(a + 1, a + n + 1, comp);
for (fac[0] = i = 1, o = h + w; i <= o; i++)
fac[i] = fac[i - 1] * i%mod;
inv[o] = ksm(fac[o], mod - 2);
for (i = o - 1; i >= 0; i--)
inv[i] = inv[i + 1] * (i + 1) % mod;
a[n + 1].x = h;
a[n + 1].y = w;
for (i = 1; i <= n + 1; i++)
{
f[i] = C(a[i].x - 1, a[i].x + a[i].y - 2);
for (j = 1; j < i; j++)
if (a[j].x <= a[i].x&&a[j].y <= a[i].y)
f[i] = (f[i] - 1LL * f[j] * C(a[i].x - a[j].x, a[i].x + a[i].y - a[j].x - a[j].y) % mod) % mod;
}
printf("%d", (f[n + 1] + mod) % mod);
return 0;
}
Codeforces559C Gerald and Giant Chess的更多相关文章
- 2018.11.07 codeforces559C. Gerald and Giant Chess(dp+组合数学)
传送门 令f[i]f[i]f[i]表示对于第iii个棋子,从(1,1)(1,1)(1,1)出发到它不经过其它棋子的方案数. 于是我们假设(h,w)(h,w)(h,w)有一个棋子,求出它的fff值就可以 ...
- dp - Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess
Gerald and Giant Chess Problem's Link: http://codeforces.com/contest/559/problem/C Mean: 一个n*m的网格,让你 ...
- CodeForces 559C Gerald and Giant Chess
C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- Gerald and Giant Chess
Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- CF559C Gerald and Giant Chess
题意 C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input ...
- E. Gerald and Giant Chess
E. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes2015-09-0 ...
- Codeforces Round #313 (Div. 1) C. Gerald and Giant Chess DP
C. Gerald and Giant Chess Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...
- codeforces(559C)--C. Gerald and Giant Chess(组合数学)
C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input st ...
- 【题解】CF559C C. Gerald and Giant Chess(容斥+格路问题)
[题解]CF559C C. Gerald and Giant Chess(容斥+格路问题) 55336399 Practice: Winlere 559C - 22 GNU C++11 Accepte ...
随机推荐
- Qt的action控件中采用默认绑定,没有connect显示绑定!!!
使用qt创建界面时,可以选用代码设计也可以选用qt design来设计.最近看我同事的代码,以前写action都是使用connect链接槽函数的, 网上大多数人都是这样,然后我就纳闷,怎么没有conn ...
- Oracle数据库操作总是显示运行中无法成功,删除表时报错 resource busy and acquire with NOWAIT specified
1.直接运行以下语句: select t2.username,t2.sid,t2.serial#,t2.logon_timefrom v$locked_object t1,v$session t2wh ...
- linux内核配置 kbuild
Linux 内核配置机制 http://blog.csdn.net/dianhuiren/article/details/6917132 linux kbuild文档 http://blog.chin ...
- linux服务器中Jenkins集成git、Gradle持续构建Springboot项目
Jenkins是用java编写的开源持续集成工具,目前被国内外各公司广泛使用.本章教大家如何在linux服务器中使用Jenkins自动发布一个可作为linux服务发布的Springboot项目. 自动 ...
- Signed Distance Field Technique
[Distance Field Technique] 一种小纹理高清放大的技术. A distance field is generated from a high resolution image, ...
- LeetCode解题思路
刷完题后,看一下其他人的solution,受益匪浅. 可以按不同的topic刷题,比如数组.字符串.集合.链表等等.先做十道数组的题,接着再做十道链表的题. 刷题,最主要的是,学习思路. 多刷几遍.挑 ...
- NIO简单理解
NIO:新IO,同步的非阻塞IO. 1.Java NIO 由以下几个核心部分组成:Channels(通道).Buffers(缓冲区).Selectors(选择器) Channels(通道) 1.所有的 ...
- c++中的类(class)-----笔记(类继承)
1,派生类继承了基类的所有成员函数和数据成员(构造函数.析构函数和操作符重载函数外). 2,当不指明继承方式时,默认为私有继承. 3,基类的私有成员仅在基类中可见,在派生类中是不可见的.基类的私有成员 ...
- HTTP 基础
HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送 ...
- c++实现中的一些注意 事项
1,尽可能延后对象中的变量定义式的出现,这样可以增加程序的清晰度,尽量少的调用构造,如果有定义变量最好在末尾定义并给予初值,这样就避免了默认构造函数的调用. 2 尽量少做转型操作. const_cas ...