$ POJ1038~\times BugsIntegratedInc: $ (复杂的状压DP)



$ solution: $

很纠结的一道题目,写了大半天,就想练练手,结果这手生的。其实根据之前那道炮兵阵地就不应该写的,但是总觉得自己的思路会好一些,码量又小。

博主的核心思路其实就是用一个二进制数来压缩三行的状态,因为二进制的左移右移很方便。然后就是如果三进制会很不好转移。

  1. 我们可以用一个二进制数来预处理压缩出第 $ i $ 往下三行的障碍状态,前 $ m $ 个二进制位表第 $ i $ 行,中间 $ m $ 个二进制位表 $ i+1 $ 行,后 $ m $ 个二进制位表第 $ i+2 $ 行

  2. 我们设一个长方体用坐上角那个点表示

  3. 我们可以用搜索来搜出一行内的长方体放置方案,这个很好写,线面代码里唯一一个手写函数就是用来求这个的。它同样用一个二进制来表示出,这个方案里三行被长方体覆盖的状况。

  4. 然后我们需要用步骤3里的单行放置方案来求出上下两行的方案拼接方案(其实就是用一个二进制将两行的方案压缩进来)。直接暴力枚举单行放置方案,再用二进制与运算来判断是否有冲突:如下

  5.      for(rg i=1;i<=tt;++i)
    for(rg j=1;j<=tt;++j)
    if(!((b[i]>>m)&b[j])){
    r[++st]=j; p[i][j]=st; //r表示方案的下面一行用的那个单行方案
    g[st]=(b[i]>>m)|b[j]; //找出两行的放置方案
    }
  6. 然后我们设状态就必须将前两行的状态都包含进去:设 $ f[i][j] $ 表示第 $ i $ 行前两行状态为 $ g[j] $ 意义在上面代码里

  7. 然后我们就可以开始常规转移,但是数组 $ r $ 和数组 $ p $ 一定要搞清楚!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define rg register int using namespace std; int n,m,ff,tt,st,ans;
int a[155];
int b[305];
int c[305];
int g[3005];
int r[3005];
int p[305][305];
int f[155][3005]; inline void dfs(int i,int v,int vv){ //用一个二进制表示一行的状态(在某一行放,下面两行都有可能被覆盖,用一个二进制将这三行压在一起)
if(i==m){b[++tt]=v; c[tt]=vv; return ;} dfs(i+1,v,vv); //导入方案
if(i+3<=m)dfs(i+3,v|(7<<i)|(7<<(i+m)),vv+1); //放入横的长方体
if(i+2<=m)dfs(i+2,v|(3<<i)|(3<<(i+m)|(3<<(i+m+m))),vv+1); //放入竖的长方体
} int main(){
rg t; cin>>t;
while(t--){
cin>>n>>m>>ff; ans=0; //读入
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
tt=0; st=0; dfs(0,0,0); //初始化
for(rg i=1;i<=tt;++i)
for(rg j=1;j<=tt;++j)
if(!((b[i]>>m)&b[j])){
r[++st]=j; p[i][j]=st; //r表示方案的下面一行用的那个单行方案
g[st]=(b[i]>>m)|b[j]; //找出两行的放置方案
}
for(rg i=1;i<=ff;++i){
rg x,y; cin>>x>>y;
a[x]|=1<<(y-1);
} a[n+1]=(1<<m)-1; //障碍的二进制读入,最后还要加一行障碍,防止长方体出界
for(rg i=1;i<=n;++i){
a[i]|=(a[i+1]<<m)|(a[i+2]<<(m+m)); //连续三行障碍压进一个二进制里
for(rg j=1;j<=st;++j)
for(rg k=1;k<=tt;++k)
if(!(((g[j]>>m)|a[i])&b[k])){ //这一行放的方案与前面的方案还有障碍不会冲突
f[i][p[r[j]][k]]=max(f[i][p[r[j]][k]],f[i-1][j]+c[k]);
ans=max(ans,f[i][p[r[j]][k]]); //因为多加了一行障碍,不用怕出界
}
} printf("%d\n",ans);
}
return 0;
}

POJ 1038 Bugs Integrated Inc (复杂的状压DP)的更多相关文章

  1. POJ 1038 Bugs Integrated, Inc.

    AC通道 神坑的一道题,写了三遍. 两点半开始写的, 第一遍是直接维护两行的二进制.理论上是没问题的,看POJ discuss 上也有人实现了,但是我敲完后准备开始调了.然后就莫名其妙的以为会超时,就 ...

  2. POJ 3311 Hie with the Pie (状压DP)

    题意: 每个点都可以走多次的TSP问题:有n个点(n<=11),从点1出发,经过其他所有点至少1次,并回到原点1,使得路程最短是多少? 思路: 同HDU 5418 VICTOR AND WORL ...

  3. POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解

    题意:n*m方格,有些格子有黑点,问你最多裁处几张2 * 3(3 * 2)的无黑点格子. 思路:我们放置2 * 3格子时可以把状态压缩到三进制: 关于状压:POJ-1038 Bugs Integrat ...

  4. POJ 2923 【01背包+状态压缩/状压DP】

    题目链接 Emma and Eric are moving to their new house they bought after returning from their honeymoon. F ...

  5. POJ 1038 Bugs Integrated, Inc. ——状压DP

    状态压缩一下当前各格子以及上面总共放了几块,只有012三种情况,直接三进制保存即可. 然后转移的时候用搜索找出所有的状态进行转移. #include <map> #include < ...

  6. poj 1038 Bugs Integrated, Inc. 题解

    提供一种代码难度比较简单的做法(可能) 状态表示: 设置状态$ f[i][j] $,表示第 \(i\) 行状态为 \(j\) 的最大放置数,因为这是个阴间题,因为题目内存设置很小,所以要用滚动数组,存 ...

  7. POJ 3311 Hie with the Pie(状压DP + Floyd)

    题目链接:http://poj.org/problem?id=3311 Description The Pizazz Pizzeria prides itself in delivering pizz ...

  8. POJ 3311 Hie with the Pie floyd+状压DP

    链接:http://poj.org/problem?id=3311 题意:有N个地点和一个出发点(N<=10),给出全部地点两两之间的距离,问从出发点出发,走遍全部地点再回到出发点的最短距离是多 ...

  9. POJ 题目2411 Mondriaan's Dream(状压DP)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13519   Accepted: 787 ...

随机推荐

  1. Unity中的动画系统和Timeline(2) 按钮动画和2D精灵动画

    按钮动画 1 创建按钮后,按钮的Button组件中,Transition我们平时用的时Tint,这次选择Animation 选择Auto Generate Animation,创建一个按钮动画 2 后 ...

  2. 【DSP开发】C6000非多核非KeyStone系列DSP中断系统

    C6000系列DSP的中断系统 上一篇介绍了C6455的GPIO系统,最后把GPIO4配置成了中断/事件模式,本文将介绍C6455的中断系统,介绍完基本概念后,给出把GPIO4映射到INT4的代码. ...

  3. python笔记之列表

    python中列表使用list类. 创建一个列表:list1 = [1,2,3,4]使用逗号隔开每个元素,使用方括号包含起来,创建空列表直接使用list2 = [] #!/usr/bin/env py ...

  4. elasticsearch的备份和恢复(转)

    vim /etc/elasticsearch/elasticsearch.yml path.repo: ["/data/backups/es_backup"] #备份目录,根据自己 ...

  5. 四则运算计算器的微信小程序_1 界面

    主界面wxml文件: page{ height:100%; } .content{ min-height:100%; display:flex; flex-direction:column; alig ...

  6. 厉害了,ES 如何做到几十亿数据检索 3 秒返回!

    一.前言 数据平台已迭代三个版本,从头开始遇到很多常见的难题,终于有片段时间整理一些已完善的文档,在此分享以供所需朋友的 实现参考,少走些弯路,在此篇幅中偏重于ES的优化,关于HBase,Hadoop ...

  7. jinja2介绍

    jinja2介绍 jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用. jinja2的优点 jin ...

  8. JS中的继承(下)

    JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...

  9. SSM和Spring Boot常用配置比较

    一.Dao层相关 1.Mysql相关: 1.1配置DataSource连接池: (1)SSM配置: <!-- 加密后配置自己写的解析文件 --> <bean class=" ...

  10. Java中的Switch....case语句:

    一.格式: switch(表达式){ case 常量表达式1:  语句1;    case 常量表达式2:  语句2;    …     case 常量表达式n:  语句n;    default: ...