51nod1486 大大走格子

n<=100000 * m<=100000的网格求不经过给定的h<=2000个点,从左上角到右下角只向右或向下走的方案数。

先来看不经过一个点:

要绕过这个点到右下角,可以先到该点右上角,再下来,或者到该点左下角,再往右。更一般的,是到该点右下角的总方案,减去经过该点的方案数。

如果这个点坐标(n,m),那么到右下角,方案数就是S(n+1,m+1)-S(n,m),其中S(i,j)=C(i+j,j),是到点(i,j)的所有方案数,自行推导。

那如果有多个点呢?我们需要不重复、不遗漏地统计“经过某个点的所有方案”。由于只向右向下,所以统计经过点(i,j)的方案时,必须保证不经过(x,y),x<=i,y<=j的所有点。

那么就按x排序再按y排序所有点,令f(i)表示到点i,不经过任何i左上方的点的方案数,则f(i)=S(Xi-1,Yi-1)-f(j)*S(Xi-Xj,Yi-Yj),其中Xj<=Xi,Yj<=Yi。先走合法方案到某个点,后面乱走到点i,这样统计方案一定不重复,因为f(j)表示的方案一定不含经过点k,Xk<=Xj,Yk<=Yj的方案,所以f(j)转移过来的方案都没经过他左上方的所有点,这样即使k的方案中可能有经过j,也不会重复。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 //#include<assert.h>
 6 //#include<iostream>
 7 using namespace std;
 8
 9 int n,m,h;
10 #define maxh 2011
11 int f[maxh];
12 struct Point
13 {
14     int x,y;
15     bool operator < (const Point &b) const
16     {return x<b.x || (x==b.x && y<b.y);}
17 }a[maxh];
18 #define maxn 200011
19 int fac[maxn],inv[maxn];
20 const int mod=1e9+7;
21 int powmod(int a,int b)
22 {
23     int ans=1;
24     for (;b;a=1ll*a*a%mod,b>>=1) if (b&1) ans=1ll*ans*a%mod;
25     return ans;
26 }
27 void pre(int n)
28 {
29     fac[0]=1;for (int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
30     inv[n]=powmod(fac[n],mod-2);for (int i=n-1;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
31 }
32 int C(int n,int m) {return 1ll*fac[n]*inv[n-m]%mod*inv[m]%mod;}
33 int S(int n,int m) {return C(n+m,n);}
34 int main()
35 {
36     scanf("%d%d%d",&n,&m,&h);
37     for (int i=1;i<=h;i++) scanf("%d%d",&a[i].x,&a[i].y);
38     sort(a+1,a+1+h);
39     a[++h].x=n;a[h].y=m;
40     pre(n+m+2);
41     f[1]=S(a[1].x-1,a[1].y-1);
42     for (int i=2;i<=h;i++)
43     {
44         f[i]=S(a[i].x-1,a[i].y-1);
45         for (int j=1;j<i;j++)
46             if (a[i].y>=a[j].y) f[i]-=1ll*f[j]*S(a[i].x-a[j].x,a[i].y-a[j].y)%mod,
47             f[i]+=f[i]<0?mod:0;
48     }
49     printf("%d\n",f[h]);
50     return 0;
51 }

时间: 2024-11-05 09:52:08

51nod1486 大大走格子的相关文章

51NOD-1486 大大走格子

有一个h行w列的棋盘,里面有一些格子是不能走的,现在要求从左上角走到右下角的方案数. Input 单组测试数据. 第一行有三个整数h, w, n(1 ≤ h, w ≤ 10^5, 1 ≤ n ≤ 2000),表示棋盘的行和列,还有不能走的格子的数目. 接下来n行描述格子,第i行有两个整数ri, ci (1 ≤ ri ≤ h, 1 ≤ ci ≤ w),表示格子所在的行和列. 输入保证起点和终点不会有不能走的格子. Output 输出答案对1000000007取余的结果. Sample Input

1344 走格子

1344 走格子 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了.问机器人最少需要有多少初始能量,才能完成整个旅程. 例如:n

HNUST-1681 机器人走格子(找规律)

1681: 机器人走格子 时间限制: 1 Sec  内存限制: 128 MB提交: 244  解决: 58[提交][状态][讨论版] 题目描述 一个长X宽Y的棋盘,有XY个格子.将机器人放在某个格子中,机器人可以沿上.下.左.右四个方向走一步到相邻的格子中,但不会越过棋盘边界. 问机器人要经过所有的格子至少一次并最终回到起点最少需要多少步?规则允许机器人多次走过同一个格子.对于X=Y=1的情形,我们认为答案为0. 输入 输入数据的第一行是一个整数T(0<T<=50),测试数据的组数. 每组测试

1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏

1289 大鱼吃小鱼 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右).问足够长的时间之后,能剩下多少条鱼? Input 第1行:1个数N,表示鱼的数量(1 <= N <= 100000). 第2 - N + 1行:每行两个数A[i], B[i],中间用空格分隔,分别表示鱼的大小及游动的方向(1 <= A[i] <= 10^9,B[i] = 0 或 1

51nod 1344 走格子(水题+贪心)

1344 走格子 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 取消关注 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了.问机器人最少需要有多少初始能量,才能完成

51Nod 1344 走格子(贪心

1344 走格子 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了.问机器人最少需要有多少初始能量,才能完成整个旅程. 例如:n = 5.{1,-2,-1,3,4} 最少需要2个初始能量,才能从1号走到5号格子.

【题解】 第五届在线编程大赛月赛第二题:走格子

题目详情 我们有一个两行n列格子的棋盘,你可以从任何位置出发.每次你可以沿着上下左右以及对角线的方向走一格(不能出去),求有多少条可能的哈密尔顿路?(即所有的格子只经过一次的路.) 例如: a b c d e f 一条可能的路径是b,f,c,e,d,a 输入格式: 多组数据,每组数据1行,包含一个正整数n表示列数. (n <= 1000) 输出格式: 每组数据输出一行包含一个整数,可能的路径条数.结果比较大,输出对10^9 + 7的结果 答题说明 输入样例 1 2 3 输出样例: 2 24 96

51Nod 1344 走格子 (贪心)

有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了.问机器人最少需要有多少初始能量,才能完成整个旅程. 例如:n = 5.{1,-2,-1,3,4} 最少需要2个初始能量,才能从1号走到5号格子.途中的能量变化如下

51nod走格子

基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 有编号1-n的n个格子,机器人从1号格子顺序向后走,一直走到n号格子,并需要从n号格子走出去.机器人有一个初始能量,每个格子对应一个整数A[i],表示这个格子的能量值.如果A[i] > 0,机器人走到这个格子能够获取A[i]个能量,如果A[i] < 0,走到这个格子需要消耗相应的能量,如果机器人的能量 < 0,就无法继续前进了.问机器人最少需要有多少初始能量,才能完成整个旅程. 例如:n = 5.{1,-2