zoukankan      html  css  js  c++  java
  • 51Nod 1486 大大走格子 —— 容斥

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

    对于每个点,求出从起点到它,不经过其他障碍点的方案数;

    求一个点时,首先得到走到它的所有方案,减去 x , y 都小于它的点的方案 * 走到该点的方案数;

    由于该点的方案也不包括其它障碍点,所以就是容斥。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int const maxn=1e5+5,mod=1e9+7;
    int h,w,n,x[maxn],y[maxn];
    ll fac[maxn<<1],ans[maxn],inv[maxn];//<<1
    struct N{int x,y;}p[maxn];
    bool cmp(N a,N b){return a.x==b.x?a.y<b.y:a.x<b.x;}
    ll pw(ll a,int b)
    {
        ll ret=1;
        for(;b;b>>=1,a=(a*a)%mod)
            if(b&1)ret=(ret*a)%mod;
        return ret;
    }
    ll C(int n,int m)
    {
        if(m==0)return 1;//!0!
        return ((fac[n]*inv[m]%mod)*inv[n-m])%mod;
    }
    void init()
    {
        fac[0]=1; int mx=h+w,mxx=max(h,w);
        for(int i=1;i<=mx;i++)fac[i]=(fac[i-1]*i)%mod;
        inv[mxx]=pw(fac[mxx],mod-2);
        for(int i=mxx-1;i>=0;i--)inv[i]=(inv[i+1]*(i+1))%mod;
    }
    int main()
    {
        scanf("%d%d%d",&h,&w,&n);
        init();
        for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y); 
        p[++n].x=h; p[n].y=w;
        sort(p+1,p+n+1,cmp);
        for(int i=1,a,b;i<=n;i++)
        {
            a=p[i].x-1,b=p[i].y-1;
            ans[i]=C(a+b,b)%mod;
            for(int j=1;j<i;j++)
            {
                if(p[j].x>p[i].x||p[j].y>p[i].y)continue;
                a=p[i].x-p[j].x; b=p[i].y-p[j].y;
                ans[i]=(ans[i]-C(a+b,b)*ans[j]%mod+mod)%mod;
            }
        }
        printf("%lld
    ",ans[n]%mod);
        return 0;
    }
  • 相关阅读:
    提高电脑运行效率
    Android_实验小心得_持续补充中......
    LNMP环境搭建wordpress
    php安装
    mysql、MariaDB(yum)
    Nginx配置(yum)
    httpd配置(yum)
    jumpserver环境搭建
    命令
    vsftpd
  • 原文地址:https://www.cnblogs.com/Zinn/p/9628217.html
Copyright © 2011-2022 走看看