• 51Nod 1486 大大走格子


    Problem

    有一个h行w列的棋盘,里面有一些格子是不能走的,现在要求从左上角走到右下角的方案数。(只能向右和向下走)

    Solution

    黑点里加入右下的点,每个点求一个ans[i],代表走到这个点的方案数。

    ans[i]初始为C(n+m-2,m-1),对于所有在它左上的点,都减去那个点的ans[j]乘i、j之间的方案数。

    (每个黑点,求ans的时候是求:不经过其左上所有的黑点,到它的方案数;用的时候是减去:经过这个点到右下的所有可能,此时路径没有经过当前黑点左上的黑点,因此每个黑点的ans是独立的。)

    Code

    #include<stdio.h>
    #include<set>
    #include<iostream>
    #include<stack>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<queue>
    #include<algorithm>
    typedef long long ll;
    typedef long double ld;
    typedef double db;
    #define io_opt ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    using namespace std;
    const int mod=1e9+7;
    inline int mo(ll a,int p){
        return a>=p?a%p:a;
    }
    inline int rd() {
        int x = 0, f = 1;
        char ch;
        while (ch < '0' || ch > '9') {
            if (ch == '-')f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return f * x;
    }
    inline ll gcd(ll x, ll y){
        return y==0?x:gcd(y,x%y);
    }
    inline ll speed(ll a,ll b,int p){
        ll cur=a,anss=1;
        while(b){
            if(b&1) anss=anss*cur%p;
            cur=cur*cur%p;
            b>>=1;
        }
        return anss%p;
    }
    const int MAXN=1e5;
    bool ipr[MAXN+20];
    int cnt,pri[MAXN/5];
    void prime(){//埃式筛法
        int N=sqrt(MAXN)+0.5,mul;
        memset(ipr,true,sizeof(ipr));
        ipr[1]=false;
        for(int i=2;i<=N;i++){
            if(ipr[i]==true){
                i==2?mul=1:mul=2;
                for(int j=i*i;j<=MAXN;j+=i*mul){
                    ipr[j]=false;
                }
            }
        }
        for(int i=2;i<=MAXN;i++){
            if(ipr[i]==true){
                pri[++cnt]=i;
            }
        }
    }
    int n,m,t;
    struct E{
        int x,y;
        ll ans;
    }e[2020];
    int cmp(E x,E y){
        if(x.x==y.x) return x.y<y.y;
        return x.x<y.x;
    }
    ll jc[200020]={1};
    ll fjc[200020]={1};
    inline ll C(int nn,int mm){
        return mo(mo(jc[nn+mm]*fjc[nn],mod)*fjc[mm],mod);
    }
    int main(){
        //io_opt;
        for(int i=1;i<=200000;i++){
            jc[i]=jc[i-1]*i%mod;
            fjc[i]=speed(jc[i],mod-2,mod);
        }
        scanf("%d%d%d",&n,&m,&t);
        for(int i=1;i<=t;i++){
            scanf("%d%d",&e[i].x,&e[i].y);
            e[i].ans=0;
        }
        e[t+1]=(E){n,m,0LL};
        sort(e+1,e+1+t,cmp);
        for(int i=1;i<=t+1;i++){
            e[i].ans=C(e[i].x-1,e[i].y-1);
            for(int j=1;j<i;j++){
                if(e[j].x<=e[i].x&&e[j].y<=e[i].y){
                    e[i].ans-=e[j].ans*C(e[i].x-e[j].x,e[i].y-e[j].y);
                }
                e[i].ans=(e[i].ans+mod*(ll)mod)%mod;
            }
        }
        printf("%lld
    ",e[t+1].ans);
        return 0;
    }
    
    
    
  • 相关阅读:
    【BZOJ3489】A simple rmq problem【kd树】
    【BZOJ2716】天使玩偶【kd树】
    Codeforces Round #520 (Div. 2)
    Codeforces Round #521 (Div. 3)
    Educational Codeforces Round 54
    【hdu3507】Print Article 【斜率优化dp】
    【HDU5992】Finding Hotels 【KD树】
    【hdu4347】The Closest M Points 【KD树模板】
    【BZOJ2806】Cheat 【广义后缀自动机+单调队列优化dp+二分】
    SDSC2018 Day1
  • 原文地址:https://www.cnblogs.com/sz-wcc/p/13194311.html
Copyright © 2020-2023  润新知