HDU 5794 A Simple Chess dp+Lucas A Simple Chess

题目链接:

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

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-----------------------------------------------------------------------