• JZOJ 1667【AHOI2009】中国象棋——dp


    题目:https://jzoj.net/senior/#main/show/1667

    只注重0、1、2的列有多少个,不注重它们的位置,就能记录了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=105,mod=9999973;
    int n,m,dp[2][N][N][N],ans,jc[N],jcn[N];
    int pw(int x,int k)
    {
        int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;
    }
    void init()
    {
        jc[0]=1;
        for(int i=1;i<=m;i++)jc[i]=(ll)jc[i-1]*i%mod;/////m not n
        jcn[m]=pw(jc[m],mod-2);
        for(int i=m-1;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod;
    }
    int C(int n,int m)
    {
        return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;
    }
    int main()
    {
        scanf("%d%d",&n,&m);dp[0][m][0][0]=1;
        init();
        for(int i=1;i<=n;i++)
        {
            int d=(i&1);
            for(int x=0;x<=m;x++)
                for(int y=0;y<=m;y++)
                {
                    int z=m-x-y;
                    dp[d][x][y][z]=dp[!d][x][y][z];
                    if(y)(dp[d][x][y][z]+=(ll)dp[!d][x+1][y-1][z]*(x+1)%mod)%=mod;//0->1
                    if(z)(dp[d][x][y][z]+=(ll)dp[!d][x][y+1][z-1]*(y+1)%mod)%=mod;//1->2
                    if(y>1)(dp[d][x][y][z]+=(ll)dp[!d][x+2][y-2][z]*C(x+2,2)%mod)%=mod;//0,0->1,1
                    if(y&&z)(dp[d][x][y][z]+=(ll)dp[!d][x+1][y][z-1]*(x+1)%mod*y%mod)%=mod;//0,1->1,2
                    if(z>1)(dp[d][x][y][z]+=(ll)dp[!d][x][y+2][z-2]*C(y+2,2)%mod)%=mod;//1,1->2,2
                }
        }
        int d=(n&1);
        for(int x=0;x<=m;x++) for(int y=0;y<=m;y++) (ans+=dp[d][x][y][m-x-y])%=mod;
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Lucene.Net
    关于数据库优化问题总结
    网页幻灯片效果
    ASP.NET邮件发送
    【收藏】悟透JavaScript(李战)
    JS之显示、隐藏控件方法
    初学自定义验证码
    js之判断浏览器类型及版本号
    js清空上传控件的值
    vs2008学习之路
  • 原文地址:https://www.cnblogs.com/Narh/p/9427241.html
Copyright © 2020-2023  润新知