• Luogu P2704 [NOI2001]炮兵阵地


    gate

    还是状压dp...

    因为int开成bool了de了好久,最后还是wjh帮忙看出来的qaq

     

    f[i][k][j]代表第i行,状态为j,上一行状态为k,上上行的状态为kk

    四重循环,保证j,k、j,kk、k,kk不冲突的前提下,有:

    f[i][k][j] = max(f[i][kk][k] + sum[j])

    因为状态太多了存不下,所以只要把可行的状态记录下来,也就是说离散化一下w

    据说还可以用滚动数组,只记录两行的(f[i%2][j][k])不过空间反正足够了

    前两行初始化要稍微注意下。

    一点以后可能有用的优化:

    1.这个题“只能放在平原上,不能放在山地上”,我原来是写完全包含 (g[j]|a[i]) == a[i]

    后来看题解a[i]存的是山地的位置,也就是  !(g[j]&a[i])

    2.这个题是横着比较短而竖着比较长而爆空间的…

    如果遇到竖着短横着长的情况,不妨把它旋转一下。这样枚举状态的循环就会变得短一些!

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define MogeKo qwq
    using namespace std;
    
    char s[15];
    int n,m,ans,cnt;
    int a[1<<11],sum[70],f[105][70][70],g[70];
    
    int main() {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++) {
            scanf("%s",s);
            for(int j = 0; j < m; j++)
                a[i] = (a[i] << 1)|(s[j] == 'H');
        }
        for(int i = 0; i < (1<<m); i++) {
            if(i&(i<<2)||i&(i<<1)||i&(i>>1)||i&(i>>2)) continue;
            g[++cnt] = i;
            for(int j = 0; i>>j; j++)
                sum[cnt] += (i>>j)&1;
            if(g[cnt]&a[1]) continue;
            f[1][0][cnt] = sum[cnt];
        }
        for(int i = 1; i <= cnt; i++)
            for(int j = 1; j <= cnt; j++) {
                if(g[j] & a[2]) continue;
                if(g[j] & g[i]) continue;
                f[2][i][j] = max(f[2][i][j],f[1][0][i] + sum[j]);
            }
    
        for(int i = 3; i <= n; i++)
            for(int j = 1; j <= cnt; j++) {
                if(g[j]&a[i]) continue;
                for(int k = 1; k <= cnt; k++)
                    for(int kk = 1; kk <= cnt; kk++) {
                        if(g[j]&g[k] || g[j]&g[kk] || g[k]&g[kk]) continue;
                        f[i][k][j] = max(f[i][k][j],f[i-1][kk][k]+sum[j]);
                        ans = max(ans,f[i][k][j]);
                    }
            }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    3D切割轮播图
    网站公共部分的复用
    Git的安装及布置
    完整轮播图
    百度检索例子
    第五章 pycharm编辑器安装和使用
    第四章 散列类型的方法
    第一章 认识爬虫以及环境安装
    主机访问Ubuntu虚拟机的jupyter
    12306购票的testerSunshine带源码刷票
  • 原文地址:https://www.cnblogs.com/mogeko/p/11713203.html
Copyright © 2020-2023  润新知