登山

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  恶梦是一个登山爱好者,今天他来到了黄山
  俗话说的好,不走回头路。所以在黄山,你只能往前走,或者往上走。
  并且很显然的是,当你走到山脊的时候,你不能够往上走,你只能往前走一步再往上走。
  抽象一点而言就是,你可以把黄山视为一个N * N格点图,恶梦从(0,0)开始出发,要走到 (N,N)。
  当他走到位置(x,y)的时候,它可以往(x + 1,y),或(x,y+1)走。
  并且当他走到(x,x)的时候,由于他已经处在了山脊上,所以他不能够往(x,x+1)方向上走。
  当恶梦兴致勃勃准备开始爬山的时候,他的同伴告诉他,黄山由于年久失修,有一些位置出现了大坑,不能走。
  恶梦觉得更刺激了,但他想先知道他能有多少种方式走到黄山顶。
  由于这个数字很大,所以你只需要将答案对10^9 + 7取模输出即可。

Input

  第一行包括两个整数N,C,分别表示你可以把黄山视作一个N * N的格点图,并且黄山上面有C个位置出现了大坑。
  接下来的C行,每行包括两个整数X,Y,表示X,Y这个位置不能走。
  保证X>=Y,也就是说(X,Y)必然在山上。
  保证这C个点互不相同。

Output

  输出只有一个整数Ans,表示恶梦爬上山顶的路径数对10^9+7取模的值。

Sample Input

  5 2
  5 0
  1 1

Sample Output

  27

HINT

  对于100%的数据,保证N<=100000,C<=1000。
  保证对于(0,0),(N,N)不存在障碍点。

Solution

  这显然是一道数学题,结合DP,我们令 f[i] 表示不经过其它障碍点,首先经过障碍点 i 的方案数。

  那么显然有:f[i] = Ways(0,0 -> i) - f[j] * Ways(i -> j)

  问题就转化为了,怎样求出满足不超过直线y=x+1从一点走向另外一点的方案数。

  

  

  

  所以Ways = ((x1, y1) -> (x2, y2)) - ((x1, y1) -> (y2-1, x2+1))

  统计答案只要加入一个(n, n)f里面计算即可。

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ;
const int MOD = 1e9 + ; int n, m;
int x, y;
int fac[ONE], inv[ONE];
int f[ONE]; struct point
{
int x, y;
}a[ONE];
bool cmp(const point &a, const point &b)
{
if(a.x != b.x) return a.x < b.x;
return a.y < b.y;
} int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} int Quickpow(int a, int b)
{
int res = ;
while(b)
{
if(b & ) res = (s64)res * a % MOD;
a = (s64)a * a % MOD;
b >>= ;
}
return res;
} void Deal_first()
{
fac[] = ;
for(int i = ; i <= * n; i++)
fac[i] = (s64)fac[i - ] * i % MOD;
inv[ * n] = Quickpow(fac[ * n], MOD - );
for(int i = * n - ; i >= ; i--)
inv[i] = (s64)inv[i + ] * (i + ) % MOD;
} int C(int n, int m)
{
if(n < || m < ) return ;
return (s64)fac[n] * inv[m] % MOD * inv[n - m] % MOD;
} void Modit(int &a)
{
if(a < ) a += MOD;
if(a >= MOD) a -= MOD;
} int Ways(point a, point b)
{
if(n < || m < ) return ;
return C(b.y - a.y + b.x - a.x, b.y - a.y);
} int Getit(point a, point b)
{
return Ways(a, b) - Ways(a, (point){b.y - , b.x + });
} int main()
{
n = get(); m = get();
Deal_first(); for(int i = ; i <= m; i++)
a[i].x = get(), a[i].y = get(); a[++m] = (point){n, n};
sort(a + , a + m + , cmp); for(int i = ; i <= m; i++)
{
Modit(f[i] = Getit((point){, }, a[i]));
for(int j = ; j < i; j++)
Modit(f[i] -= (s64)f[j] * Getit(a[j], a[i]) % MOD);
} printf("%d", f[m]);
}

【Foreign】登山 [DP][数学]的更多相关文章

  1. # E. Mahmoud and Ehab and the xor-MST dp/数学+找规律+xor

    E. Mahmoud and Ehab and the xor-MST dp/数学/找规律 题意 给出一个完全图的阶数n(1e18),点由0---n-1编号,边的权则为编号间的异或,问最小生成树是多少 ...

  2. Codeforces Beta Round #2B(dp+数学)

    贡献了一列WA.. 数学很神奇啊 这个题的关键是怎么才能算尾0的个数 只能相乘 可以想一下所有一位数相乘 除0之外,只有2和5相乘才能得到0 当然那些本身带0的多位数 里面肯定含有多少尾0 就含有多少 ...

  3. zznu 1255 数字统计(数位DP, 数学方法)

    最近在学数位DP, 感觉还是满有收获的! 做了几个题之后想起来自己OJ上曾经做的一道题,以前是用数学方法写的,现在改用数位DP来写了一遍. 题目: 1255: 数字统计 时间限制: 1 Sec  内存 ...

  4. hdu4035 Maze 【期望dp + 数学】

    题目链接 BZOJ4035 题解 神题啊...orz 不过网上题解好难看,数学推导不写\(Latex\)怎么看..[Latex中毒晚期] 我们由题当然能很快写出\(dp\)方程 设\(f[i]\)表示 ...

  5. ZOJ3872 Beauty of Array---规律 | DP| 数学能力

    传送门ZOJ 3872 Beauty of Array Time Limit: 2 Seconds      Memory Limit: 65536 KB Edward has an array A  ...

  6. [CSP-S模拟测试]:题(DP+数学)

    题目描述 出个题就好了.这就是出题人没有写题目背景的原因.你在平面直角坐标系上.你一开始位于$(0,0)$.每次可以在上/下/左/右四个方向中选一个走一步.即:从$(x,y)$走到$(x,y+1),( ...

  7. [CSP-S模拟测试]:小奇的矩阵(matrix)(DP+数学)

    题目背景 小奇总是在数学课上思考奇怪的问题. 题目描述 给定一个$n\times m$的矩阵,矩阵中的每个元素$a_{i,j}$为正整数.接下来规定:    $1.$合法的路径初始从矩阵左上角出发,每 ...

  8. HDU 4599 Dice (概率DP+数学+快速幂)

    题意:给定三个表达式,问你求出最小的m1,m2,满足G(m1) >= F(n), G(m2) >= G(n). 析:这个题是一个概率DP,但是并没有那么简单,运算过程很麻烦. 先分析F(n ...

  9. HDU 4489 The King’s Ups and Downs (DP+数学计数)

    题意:给你n个身高高低不同的士兵.问你把他们按照波浪状排列(高低高或低高低)有多少方法数. 析:这是一个DP题是很明显的,因为你暴力的话,一定会超时,应该在第15个时,就过不去了,所以这是一个DP计数 ...

随机推荐

  1. 《梦断代码Dreaming In Code》阅读计划

    书籍是人类宝贵的精神财富,读书是人们重要的学习方式,是人生奋斗的航灯,是文化传承的通道,是人类进步的阶梯.学生作为学习人群的主体,必须把读书作为头等大事.学校就是一个学生在教师指导下自主读书的空间,而 ...

  2. Python实现XML的操作

    本文从以下两个方面, 用Python实现XML的操作: 一. minidom写入XML示例1 二. minidom写入XML示例2 三. ElementTree写入/修改示例 四. ElementTr ...

  3. Python文件操作大全,随机删除文件夹内的任意文件

     在读文件的时候往往需要遍历文件夹,python的os.path包含了很多文件.文件夹操作的方法: os.path.abspath(path) #返回绝对路径os.path.basename(path ...

  4. Java接口成员变量

    定义接口    使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,当中接口体由常量定义和方法定义两部分组成.定义接口的基本格式例如以下: [修饰符] inter ...

  5. SPD各模块总结

    一.用户角色绑定节点 1.库存操作员.库存主管.验货操作员:绑定任一节点 2.采购操作员.公药操作员:只能绑定药库节点 3.退库操作员.药品申领员:绑定药库以外的节点 二.采购计划模块 1.采购计划的 ...

  6. 单选 name的值相同时候 就会产生互斥现象

  7. BZOJ 1806 矿工配餐(DP)

    很水的DP. 因为每一个餐车的加入只需要知道当前矿洞的前两个餐车种类就行了.而餐车一共就三种. 所以令dp[i][Sa][Sb]表示前i辆餐车送餐完毕后第一个矿洞的前两个餐车种类为Sa,第二个矿洞的前 ...

  8. P1349 广义斐波那契数列

    题目描述 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数. 输入输出格 ...

  9. 【刷题】BZOJ 4516 [Sdoi2016]生成魔咒

    Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例 ...

  10. 用Matlab对数据进行线性拟合算法

    http://www.cnblogs.com/softlin/p/5965939.html 挖坑