zoukankan      html  css  js  c++  java
  • Codeforces 559C:Gerald and Giant Chess/51nod 1486:大大走格子

    Codeforces 559C:Gerald and Giant Chess

    题目链接:Codeforces http://codeforces.com/problemset/problem/559/C

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

    题目大意:有一个$h imes w$的棋盘,里面有一些格子是不能走的,只能每次向右边或者下面移动,现在要求从左上角走到右下角的方案数。

    组合数+容斥原理

    将不能走的格子的坐标按横坐标为第一关键字、纵坐标为第二关键字升序排序(按纵坐标为第一关键字、横坐标为第二关键字升序排序也可),用$dp[i]$维护从左上角移动到当前不能走的格子的方案数,根据组合数的性质及容斥原理可以得到:$dp[i]=C_{p[i].x}^{p[i].x+p[i].y}-sum_{k=0}^{i-1}(dp[k] imes C_{p[i].x-p[k].x}^{p[i].x+p[i].y-p[k].x-p[k].y})$.

    故从左上角走到右下角的方案数$ans=C_{h}^{h+w}-sum_{i=0}^n(dp[i] imes C_{h-p[i].x}^{h+w-p[i].x-p[i].y})$.

    代码如下:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #define N 200005
     5 #define M 2005
     6 using namespace std;
     7 typedef long long ll;
     8 struct P{
     9     int x,y;
    10     friend bool operator < (P a,P b){
    11         if(a.x==b.x)return a.y<b.y;
    12         return a.x<b.x;
    13     }
    14 }p[M];
    15 ll dp[M],fac[N],inv[N],ans,m=1000000007;
    16 int h,w,n;
    17 ll Minus(ll a, ll b){return (a-b+m)%m;}
    18 ll Mul(ll a, ll b){return (a*b)%m;}
    19 ll pow_mod(ll a, ll n){
    20     ll r=1;
    21     while(n){
    22         if(n&1)r=Mul(r,a);
    23         a=Mul(a,a);
    24         n>>=1;
    25     }
    26     return r;
    27 }
    28 ll Inv(ll a){return pow_mod(a,m-2);}
    29 void init(){
    30     fac[0]=inv[0]=1;
    31     for(int i=1;i<=200000;++i){
    32         fac[i]=Mul(fac[i-1],i);
    33         inv[i]=Inv(fac[i]);
    34     }
    35 }
    36 ll C(ll x,ll y){return Mul(Mul(fac[x],inv[x-y]),inv[y]);}
    37 int main(void){
    38     init();
    39     scanf("%d%d%d",&h,&w,&n);
    40     h--;w--;
    41     for(int i=0;i<n;++i){
    42         scanf("%d%d",&p[i].x,&p[i].y);
    43         p[i].x--;p[i].y--;
    44     }
    45     sort(p,p+n);
    46     ans=C(h+w,h);
    47     for(int i=0;i<n;++i){
    48         dp[i]=C(p[i].x+p[i].y,p[i].x);
    49         for(int j=0;j<i;++j)
    50             if(p[i].x>=p[j].x&&p[i].y>=p[j].y)
    51                 dp[i]=Minus(dp[i],Mul(dp[j],C(p[i].x+p[i].y-p[j].x-p[j].y,p[i].x-p[j].x)));
    52         ans=Minus(ans,Mul(dp[i],C(h+w-p[i].x-p[i].y,h-p[i].x)));
    53     }
    54     printf("%lld
    ",ans);
    55 }
  • 相关阅读:
    iOS NSProgress的使用
    GIT的 .gitignore 配置
    MagicalRecord入门教程
    CoreData的数据存储
    NSLog打印信息的从新设置
    大石头得博客
    exc_bad_access(code=1, address=0x789870)野指针错误
    oc 获取当前设备系统的版本号
    免证书真机调试脚本iphoneentitlements
    支持非arc
  • 原文地址:https://www.cnblogs.com/barrier/p/6739884.html
Copyright © 2011-2022 走看看