zoukankan      html  css  js  c++  java
  • 51nod 1486

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1486

    1486 大大走格子

    题目来源: CodeForces
    基准时间限制:1 秒 空间限制:131072 KB 分值: 160 难度:6级算法题
    收藏
    关注

    有一个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取余的结果。
    Input示例
    3 4 2
    2 2
    2 3
    Output示例
    2
     跟前面做过的很类似,但是增加了一些障碍格子,很闹心啊。。。容斥也不太懂,看了dp的作法还挺好懂的把,写的太丑被卡时一早上。。。
    我们不妨计算出所有的方案然后减去有障碍格子的方案,令f[i]表示从(1,1)到第i个障碍点的合法路径,也就是说除了i点,路径上得点都合法。
    这样的话不难得出方程  f[i]=C(xi+yi-2,xi-1)-Σj=1i-1f[j]*C(xi+yi-xj-yj,xi-xj) ;
    这个方程相当于枚举了所有不合法的路径中第一个障碍格子,显然之后的所有路径都至少包含一个障碍格,所以都是非法的,
    这个方程前面就是所有的路径方案,后面就是所有的包含障碍的路径方案,减去就是要求的状态了,
    显然对于(a,b)-(c,d)格子间所有的路径数我们根据组合数能轻易的得到,打表就好了,注意并不是i之前的所有点都一定能到达i,记得判断一下。
    如果把(h,w)看做是一个最后的障碍点的话,ans=f[n+1].
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 LL mod=1e9+7;
     5 LL dp[2005];
     6 LL f[200005],inv[200005];
     7 struct node{int x,y;}P[2005];
     8 int read(){
     9     int x=0;char c=getchar();
    10     while(!isdigit(c)) c=getchar();
    11     while(isdigit(c)) x=x*10+c-'0',c=getchar();
    12     return x;
    13 }
    14 bool cmp(node A,node B)
    15 {
    16     if(A.x==B.x) return A.y<B.y;
    17     return A.x<B.x;
    18 }
    19 LL qpow(LL a,LL b)
    20 {
    21     LL r=1;
    22     while(b){
    23         if(b&1) r=r*a%mod;
    24         a=a*a;
    25         b>>=1;
    26     }
    27     return r;
    28 }
    29 inline LL C(LL N,LL M) {return f[N]*inv[M]%mod*inv[N-M]%mod;}
    30 int main()
    31 {
    32     LL h,w,n,i,j,k;
    33     scanf("%lld%lld%lld",&h,&w,&n);
    34     for(i=1;i<=n;++i)  P[i].x=read(),P[i].y=read();
    35     sort(P+1,P+1+n,cmp);
    36     P[n+1].x=h; P[n+1].y=w;
    37     inv[0]=f[0]=1;
    38     for(i=1;i<=h+w;++i)
    39     {
    40         f[i]=i*f[i-1]%mod;
    41         inv[i]=qpow(f[i],mod-2);
    42     }
    43     dp[1]=C(P[1].x+P[1].y-2,P[1].x-1);
    44     for(i=2;i<=n+1;++i)
    45     {
    46         LL s=0;
    47         for(j=1;j<i;++j)
    48         {
    49           if(P[j].x<=P[i].x&&P[j].y<=P[i].y)
    50           s=(s+dp[j]*C(P[i].x+P[i].y-P[j].x-P[j].y,P[i].x-P[j].x))%mod;
    51         }
    52         dp[i]=(C(P[i].x+P[i].y-2,P[i].x-1)-s+mod)%mod;
    53     }
    54     printf("%lld
    ",dp[n+1]);
    55     return 0;
    56 }
  • 相关阅读:
    Space Ant(极角排序)
    Marriage Match II(二分+并查集+最大流,好题)
    Leapin' Lizards(经典建图,最大流)
    Food(最大流)
    99. Recover Binary Search Tree
    97. Interleaving String
    100. Same Tree
    98. Validate Binary Search Tree
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
  • 原文地址:https://www.cnblogs.com/zzqc/p/7388679.html
Copyright © 2011-2022 走看看