• bzoj4806 炮——DP


    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4806

    看到这题首先会想到状压什么乱七八糟的,然而很难做;

    其实,因为求的是方案数,所以并不需要关注炮摆放的位置,而只需要关注数量;

    f[i][j][k] 表示第 i 行及以前共有 j 个有 0 炮的列和 k 个有 1 炮的列,就可以转移了。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    int const mod=999983,maxn=105;
    ll n,m,f[maxn][maxn][maxn],ans;
    ll C(ll x){return ((x-1)*x/2)%mod;}//不是(x+1) !!
    int main()
    {
        scanf("%d%d",&n,&m);
        f[0][m][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=0;j<=m;j++)//0
                for(int k=0;k<=m-j;k++)//1
                {
                    (f[i][j][k]+=f[i-1][j][k])%=mod;//放0个
                    if(k>=0&&j<m)(f[i][j][k]+=f[i-1][j+1][k-1]*(j+1))%=mod;//0 -> 1   //别写成 if(k&&j<m) !!
                    if(k<m)(f[i][j][k]+=f[i-1][j][k+1]*(k+1))%=mod;//1 -> 2
                    if(j<m)(f[i][j][k]+=f[i-1][j+1][k]*(j+1)*k)%=mod;//0 1 -> 1 2 
                    if(k-2>=0&&j+2<=m)(f[i][j][k]+=f[i-1][j+2][k-2]*C(j+2))%=mod;//0 0 -> 1 1
                    if(k+2<=m)(f[i][j][k]+=f[i-1][j][k+2]*C(k+2))%=mod;//1 1 -> 2 2
                }
        for(int j=0;j<=m;j++)
            for(int k=0;k<=m;k++)
                (ans+=f[n][j][k])%=mod;
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    DockerFile构建步骤及命令
    linux安装nginx及常用命令
    docker常用命令
    Docker安装
    获取TrustedInstaller权限
    获取本机公网ip的url地址
    centOS7配置ip
    VS Code配置c语言环境
    Linux l 2.4.20-8 # 溢出
    VMware Destination Host Unreachable
  • 原文地址:https://www.cnblogs.com/Zinn/p/9163646.html
Copyright © 2020-2023  润新知