• BZOJ 1801 [Ahoi2009]中国象棋(线性动规)(洛谷P2051)


    题意:就是在n*m的格子中放“炮”(中国象棋中的棋子)问有多少种放法,使得没有任意的两个炮相互攻击

    思路:我们很容易的得到一列或者一行中最多放下两个炮(我也只能得到这些了,满脑子状压,但数据范围有100),这篇博客些的很好(传送门),我们定义dp[i][j][k]代表前i行我们有j列式有2个棋子,有k列是一个棋子,那么我们空的列的个数为m-i-j,我们在每行填的时候最多填2个,这样保证了我们每行不会多于2个。然后就是分情况讨论了

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    inline LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    const LL MOD=9999973;
    LL dp[107][107][107];
    
    int main()
    {
        int n=read(),m=read();
        dp[0][0][0]=1;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                for(int k=0;k<=m-j;k++){
                    LL res=0;
                    res+=dp[i-1][j][k];
                    if(j)res+=dp[i-1][j-1][k+1]*(k+1);
                    if(k)res+=dp[i-1][j][k-1]*(m-j-k+1);
                    if(j&&k)res+=dp[i-1][j-1][k]*k*(m-j-k+1);
                    if(j>1)res+=dp[i-1][j-2][k+2]*(k+2)*(k+1)/2;
                    if(k>1)res+=dp[i-1][j][k-2]*(m-j-k+2)*(m-j-k+1)/2;
                    dp[i][j][k]=res%MOD;
                }
            }
        }
        LL ans=0;
        for(int i=0;i<=m;i++){
            for(int j=0;j<=m-i;j++){
                ans=(ans+dp[n][i][j])%MOD;
            }
        }
        printf("%lld
    ",ans%MOD);
        return 0;
    }
  • 相关阅读:
    HTML5和CSS3的学习视频
    webpack中bundler源码编写2
    webpack中bundler源码编写
    webpack中如何编写一个plugin
    webpack多页面打包配置
    webpack中配置eslint
    webpack解决单页面路由问题
    webpack中使用WebpackDevServer实现请求转发
    webpack中typeScript的打包配置
    rsync 同步
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9791130.html
Copyright © 2020-2023  润新知