HDU 4832 Chess

来源:互联网 发布:mac book pro 2016颜色 编辑:程序博客网 时间:2024/05/22 08:12
/* dp预处理再加组合数 题意:在n*m的格子上有一个棋子,它的移动规则(设初始点为(x,y)):可以移到(x+1,y),(x+2,y),(x-1,y),(x-2,y),(x,y+1),(x,y+2),(x,y-1),(x,y-2) 解法:n^2 dp预处理,再组合数求解.    先dp预处理出横向和纵向走i步的总的方法数,则最后答案为sigma(C(k,i)*e[i]*f[i]) 注意特判n=1,m=1的情况,这时候应当输出0 */#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 1111#define mod 9999991int dp1[maxn][maxn];int e[maxn];int dp2[maxn][maxn];int f[maxn];int cb[maxn][maxn];#define LL long longint calc(int n, int k){    if (!k || n == k)return 1;    if (~cb[n][k])return cb[n][k];    return cb[n][k] = (calc(n - 1, k - 1) + calc(n - 1, k)) % mod;}int main(){    int T;    scanf("%d",&T);    int kase=1;    memset(cb,-1,sizeof(cb));    while(T--)    {        memset(dp1,0,sizeof(dp1));        memset(dp2,0,sizeof(dp2));        memset(e,0,sizeof(e));        memset(f,0,sizeof(f));        int n,m,k,x0,y0;        scanf("%d%d%d%d%d",&n,&m,&k,&x0,&y0);        if(n==1&&m==1)        {            printf("Case #%d:\n0\n",kase++);            continue;        }        dp1[0][x0]=1;        for(int i=1;i<=k;i++)        {            for(int j=1;j<=n;j++)            {                if(j+1<=n)  dp1[i][j]=(dp1[i][j]+dp1[i-1][j+1])%mod;                if(j+2<=n)  dp1[i][j]=(dp1[i][j]+dp1[i-1][j+2])%mod;                if(j-1>=1)  dp1[i][j]=(dp1[i][j]+dp1[i-1][j-1])%mod;                if(j-2>=1)  dp1[i][j]=(dp1[i][j]+dp1[i-1][j-2])%mod;            }        }        for(int i=0;i<=k;i++)        {            for(int j=1;j<=n;j++)            {                e[i]=(e[i]+dp1[i][j])%mod;            }        }        dp2[0][y0]=1;        for(int i=1;i<=k;i++)        {            for(int j=1;j<=m;j++)            {                if(j+1<=m)  dp2[i][j]=(dp2[i][j]+dp2[i-1][j+1])%mod;                if(j+2<=m)  dp2[i][j]=(dp2[i][j]+dp2[i-1][j+2])%mod;                if(j-1>=1)  dp2[i][j]=(dp2[i][j]+dp2[i-1][j-1])%mod;                if(j-2>=1)  dp2[i][j]=(dp2[i][j]+dp2[i-1][j-2])%mod;            }        }        for(int i=0;i<=k;i++)        {            for(int j=1;j<=m;j++)            {                f[i]=(f[i]+dp2[i][j])%mod;            }        }        LL ans=0;        for(int i=0;i<=k;i++)        {            //printf("%d %d\n",e[i],f[i]);            LL v=calc(k,i);            v=v*e[i]%mod;            v=v*f[k-i]%mod;            ans=(ans+v)%mod;        }        //printf("%d %d\n",dp1[2][1],dp2[2][1]);        printf("Case #%d:\n%lld\n",kase++,(ans+mod)%mod);    }    return 0;}

0 0
原创粉丝点击