zoukankan      html  css  js  c++  java
  • HDU 5794 A Simple Chess dp+Lucas

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5794

    A Simple Chess

    Time Limit: 2000/1000 MS (Java/Others)
    Memory Limit: 65536/65536 K (Java/Others)
    #### 问题描述 > There is a n×m board, a chess want to go to the position > (n,m) from the position (1,1). > The chess is able to go to position (x2,y2) from the position (x1,y1), only and if only x1,y1,x2,y2 is satisfied that (x2−x1)2+(y2−y1)2=5, x2>x1, y2>y1. > Unfortunately, there are some obstacles on the board. And the chess never can stay on the grid where has a obstacle. > I want you to tell me, There are how may ways the chess can achieve its goal. #### 输入 > The input consists of multiple test cases. > For each test case: > The first line is three integers, n,m,r,(1≤n,m≤1018,0≤r≤100), denoting the height of the board, the weight of the board, and the number of the obstacles on the board. > Then follow r lines, each lines have two integers, x,y(1≤x≤n,1≤y≤m), denoting the position of the obstacles. please note there aren't never a obstacles at position (1,1). #### 输出 > For each test case,output a single line "Case #x: y", where x is the case number, starting from 1. And y is the answer after module 110119. #### 样例 > **sample input** > 1 1 0 > 3 3 0 > 4 4 1 > 2 1 > 4 4 1 > 3 2 > 7 10 2 > 1 2 > 7 1 > > **sample output** > Case #1: 1 > Case #2: 0 > Case #3: 2 > Case #4: 1 > Case #5: 5

    题意

    n*m的大棋盘,有r个障碍物,你在1,1,并且每次只能往左下走日子步,问到达(n,m)的方案数

    题解

    Lucas+dp.

    预备:设从i点到j点过程中走横日走了x步,走竖日走了y步,则有方程2x+y==n&&x+2y==m --x=(2n-m)/3,y=(2m-n)/3。
    所以方案数为C[x+y][x]。这个需要用卢卡斯处理出来。

    先把所有障碍点从左上到右下排序。
    dp[i]表示从1,1到(pt[i].x,pt[i].y)障碍的不经过任意其他位于它左上的障碍的情况数,则dp[i]=dp[i]-sigma(dp[j]*j到i点的所有方案数)。

    代码

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define pb(v) push_back(v)
    #define sz() size()
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long  LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    const double PI=acos(-1.0);
    
    //start----------------------------------------------------------------------
    
    const int maxn=111;
    const int mod=110119;
    const int maxm=mod+10;
    
    LL n,m; int r;
    pair<LL,LL> pt[maxn];
    LL facinv[maxm],inv[maxm],fac[maxm];
    LL dp[maxn];
    
    LL get_C(LL n,LL m){
        if(n<0||m<0||n<m) return 0;
        return fac[n]*facinv[m]%mod*facinv[n-m]%mod;
    }
    
    LL Lucas(LL n,LL m,int mod){
        if(m==0) return 1LL;
        return get_C(n%mod,m%mod)*Lucas(n/mod,m/mod,mod)%mod;
    }
    
    LL calc(int i,int j){
        LL n=pt[j].X-pt[i].X;
        LL m=pt[j].Y-pt[i].Y;
        if((n+m)%3) return 0;
        LL sum=(n+m)/3;
        if(n<0||m<0) return 0;
        return Lucas(sum,n-sum,mod);
    }
    
    void pre(){
        fac[0]=fac[1]=1;
        facinv[0]=facinv[1]=1;//facinv[0]=1!!!!
        inv[1]=1;
        rep(i,2,maxm){
            fac[i]=fac[i-1]*i%mod;
            inv[i]=(mod-mod/i)*inv[mod%i]%mod;
            facinv[i]=facinv[i-1]*inv[i]%mod;
        }
    }
    
    int main(){
        pre();
        int kase=0;
        while(scanf("%lld%lld%d",&n,&m,&r)==3){
            clr(dp,0);
            int flag=0;
            rep(i,1,r+1){
                scanf("%lld%lld",&pt[i].X,&pt[i].Y);
                if(pt[i].X==n&&pt[i].Y==m){
                    flag=1;
                }
            }
            if(flag){
                printf("Case #%d: 0
    ",++kase);
                continue;
            }
            pt[0].X=1,pt[0].Y=1;
            pt[r+1].X=n,pt[r+1].Y=m;
            
            sort(pt+1,pt+r+1);
            dp[0]=1;
            rep(i,1,r+2){
                dp[i]=calc(0,i);
                rep(j,1,i){
                    dp[i]-=dp[j]*calc(j,i)%mod;
                    dp[i]=(dp[i]%mod+mod)%mod;
                }
            }
            printf("Case #%d: %lld
    ",++kase,dp[r+1]);
        }
        return 0;
    }
    
    //end-----------------------------------------------------------------------
  • 相关阅读:
    【LeetCode】226. Invert Binary Tree
    【LeetCode】235. Lowest Common Ancestor of a Binary Search Tree
    【LeetCode】191. Number of 1 Bits
    【LeetCode】122. Best Time to Buy and Sell Stock II
    【LeetCode】100. Same Tree
    【LeetCode】237. Delete Node in a Linked List
    【LeetCode】136. Single Number
    【LeetCode】104. Maximum Depth of Binary Tree
    svn tree conflicts 解决方法
    sed详解
  • 原文地址:https://www.cnblogs.com/fenice/p/5755223.html
Copyright © 2011-2022 走看看