• 《算法竞赛进阶指南》0x5C计数DP Gerald & Giant Chess


    题目链接:https://www.acwing.com/problem/content/description/308/

    给定一个h*w的棋盘,上面有少于2000个黑色格子,其他是白色,问不经过黑色格子从(1,1)走到(h,w)的路线有多少个?

    将黑色格子按照(x,y)进行排序,设计f[i]为从(1,1)走到第i个黑色格子不经过其他黑色格子的方案数量,通过容斥原理,只需要计算至少经过一个黑色格子的方案数量,枚举第一个经过的黑色格子就能算出来,预处理出乘法逆元就能快速计算阶乘。

    将最后一个点当做黑色格子就可以用f[n+1]代替结果。

    注意:操作符定义中按照两个维度进行定义的时候不能用return (x==b.x && y<=b.y) || (x<=b.x)。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 2010,M=200010;
    const int mod = 1000000007;
    typedef long long ll;
    #define PII pair<int,int>
    struct node{
        int x,y;
        bool operator < (const node &a)const {
            if(x==a.x)return y<=a.y;
            else return x<=a.x;
        }
    }a[N];
    int f[N];
    ll jc[M],jcinv[M];
    int h,w,n;
    ll ksm(ll a,int k){
        ll ans=1;
        while(k){
            if(k&1)ans=ans*a %mod;
            a=a*a %mod;
            k>>=1;
        }
        return ans;
    }
    int C(int n,int m){//%运算和* /是同一个优先级 
        return jc[n]*jcinv[m]%mod * jcinv[n-m]%mod;
    }
    int main(){
        cin>>h>>w>>n;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
        }
        sort(a+1,a+n+1);
        a[n+1].x=h,a[n+1].y=w;
        a[0].x=a[0].y=1;
        
        jc[0]=1;
        jcinv[0]=1;
        for(int i=1;i<=200000;i++){//预处理阶乘逆元和阶乘 
            jc[i]=jc[i-1]*i %mod;
            jcinv[i]=ksm(jc[i],mod-2);
        }
        
        f[0]=1;
        for(int i=1;i<=n+1;i++){
            f[i]=C(a[i].x-1+a[i].y-1,a[i].x-1);
            for(int j=1;j<i;j++){
                if(a[j].x>a[i].x || a[j].y>a[i].y)continue;
                f[i] = (f[i] - (ll)f[j] * C(a[i].x + a[i].y - a[j].x - a[j].y, a[i].x - a[j].x)) % mod;
            }
        }
        
        cout<<(f[n+1]+mod)%mod<<endl;
        
        return 0;
    }
  • 相关阅读:
    python全栈开发day20-类的三大特性继承、多态、封装
    python全栈开发day19-面向对象初识
    python全栈开发day21-2 几个装饰器总结
    python全栈开发day16-正则表达式和re模块
    python全栈开发day15-递归函数、二分查找
    python运算符优先级
    动手动脑4
    动手动脑3
    查询对象个数
    动手动脑2
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13444180.html
Copyright © 2020-2023  润新知