poj 1038 Bugs Integrated, Inc. 题解
提供一种代码难度比较简单的做法(可能)
状态表示:
设置状态$ f[i][j] $,表示第 \(i\) 行状态为 \(j\) 的最大放置数,因为这是个阴间题,因为题目内存设置很小,所以要用滚动数组,存储两行的状态就够了。
状态用三进制表示:
0 表示当前行和上一行均可用
1 表示当前行可用,上一行不可用
2 表示当前行和上一行都不可用
为了方便不过常数确实略大,我们用两个数组 \(pre\) , \(now\) 分别存放上一行和当前行的状态
那么就有:
inline int getstate(int a[])//存放状态
{
int temp=0;
for(register int i=1;i<=m;i++)
temp+=a[i]*t[i];
return temp;
}
inline int getstring(int temp,int*a)//取出状态
{
for(register int i=1;i<=m;i++)
{
a[i]=temp%3;
temp/=3;
}
}
判断放矩形(设要放矩形的左下角为 (i,j) ):
横放:
$ state(i,j)0 && state(i,j+1)0&& state(i,j+2)==0 \ \ \ \ \ $ \((j+2 \le m\),废话\()\)
竖放:
$ state(i,j)0 && state(i,j+1)0 && state(i-1,j)0 && state(i-1,j+1)0 $ $\ \ \ \ \ $ \((j+1 \le m\),二度废话\()\)
DP过程:
显然,当我们知道第\(i\)行状态,和第\(i-1\)行初始状态时,就可以愉快地DP了,因为状态转换略显复杂写成循环的话可能需要很多层,所以可以用大法师\(DFS\)来写。
设置dfs参数分别为,试图放置的坐标,放置矩形的数量,第\(i\)行状态:
如果足横放,竖放,不放的情况,分别搜一下就行。
Code:
#include<bits/stdc++.h>
using namespace std;
int n,m,k,D;
int mp[151][15];
int f[2][59050];//f[i][j] i是滚动数组,j存放状态
int now[15],pre[15],t[15];//pre为i-1行,now为第i行
//0 表示当前行和上一行均可用
//1 表示当前行可用,上一行不可用
//2 表示当前行和上一行都不可用
inline int qr()
{
char a=0;int w=1,x=0;
while(a<'0'||a>'9'){if(a=='-')w=-1;a=getchar();}
while(a<='9'&&a>='0'){x=(x<<3)+(x<<1)+(a^48);a=getchar();}
return x*w;
}
inline int getstate(int a[])//存放状态
{
int temp=0;
for(register int i=1;i<=m;i++)
temp+=a[i]*t[i];
return temp;
}
inline int getstring(int temp,int*a)//取出状态
{
for(register int i=1;i<=m;i++)
{
a[i]=temp%3;
temp/=3;
}
}
void dfs(int i,int j,int num,int state)//(i,j)为尝试放矩形的右下角位置,num为放矩形数量,state为第i行状态
{
f[i%2][state]=max(f[i%2][state],num);//更新最大值
int k;
if(j>=m)
return ;
if(j<m-1&&now[j]==0&&now[j+1]==0&&now[j+2]==0)//这一行加上一行能横放一个
{
now[j]=now[j+1]=now[j+2]=2;
k=getstate(now);
dfs(i,j+3,num+1,k);
now[j]=now[j+1]=now[j+2]=0;
}
if(j<m&&pre[j]==0&&pre[j+1]==0&&now[j]==0&&now[j+1]==0)//这一行和上两行能竖放一个
{
now[j]=now[j+1]=2;
k=getstate(now);
dfs(i,j+2,num+1,k);
now[j]=now[j+1]=0;
}
dfs(i,j+1,num,state);//不放矩形
}
int main()
{
D=qr();
t[1]=1;
for(register int i=2;i<=11;i++)
t[i]=t[i-1]*3;
while(D--)
{
n=qr();
m=qr();
k=qr();
memset(mp,0,sizeof(mp));
while(k--)
mp[qr()][qr()]=1;
for(register int i=0;i<t[m+1];i++)
f[1][i]=-1;
for(register int i=1;i<=m;i++)//第一行的上一行无法利用
pre[i]=mp[1][i]+1;//记录初始状态
int state=getstate(pre);
f[1][state]=0;
for(register int i=2;i<=n;i++)
{
for(register int j=0;j<t[m+1];j++)//预处理第i行状态
f[i%2][j]=-1;
for(register int j=0;j<t[m+1];j++)
{
if(f[(i+1)%2][j]==-1)
continue;
getstring(j,pre);//取出状态j
for(register int k=1;k<=m;k++)
{
if(mp[i][k]==1)//这个块坏了这一行跟上一行都用不了
now[k]=2;
else//块没坏
if(pre[k]==2)//上一行用不了
now[k]=1;//只能用本行
else
now[k]=0;//本行和上一行都能用
}
state=getstate(now);
dfs(i,1,f[(i+1)%2][j],state);//从j状态转移到state状态
}
}
int ans=0;
for(register int i=0;i<t[m+1];i++)//统计答案
ans=max(ans,f[n%2][i]);
printf("%d\n",ans);
}
return 0;
}
poj 1038 Bugs Integrated, Inc. 题解的更多相关文章
- POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解
题意:n*m方格,有些格子有黑点,问你最多裁处几张2 * 3(3 * 2)的无黑点格子. 思路:我们放置2 * 3格子时可以把状态压缩到三进制: 关于状压:POJ-1038 Bugs Integrat ...
- POJ 1038 Bugs Integrated, Inc.
AC通道 神坑的一道题,写了三遍. 两点半开始写的, 第一遍是直接维护两行的二进制.理论上是没问题的,看POJ discuss 上也有人实现了,但是我敲完后准备开始调了.然后就莫名其妙的以为会超时,就 ...
- POJ 1038 Bugs Integrated, Inc. ——状压DP
状态压缩一下当前各格子以及上面总共放了几块,只有012三种情况,直接三进制保存即可. 然后转移的时候用搜索找出所有的状态进行转移. #include <map> #include < ...
- POJ 1038 Bugs Integrated Inc (复杂的状压DP)
$ POJ~1038~~\times Bugs~Integrated~Inc: $ (复杂的状压DP) $ solution: $ 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前 ...
- POJ 1038 Bug Integrated Inc(状态压缩DP)
Description Bugs Integrated, Inc. is a major manufacturer of advanced memory chips. They are launchi ...
- [CEOI2002]Bugs Integrated, Inc. 题解
又是一道神仙题,又是题解看不懂-- 好时代,来临力-- 时隔一个世纪来补题解了-- 之前太垃圾了,脑子有点问题,所以没看懂题解.今天再看这道题虽然还是很毒瘤,但也没有想象得那么难. 先观察芯片的形状, ...
- POJ1038 Bugs Integrated, Inc.
题目来源:http://poj.org/problem?id=1038 题目大意: 有一家芯片公司要在一块N*M的板子上嵌入芯片,其中1<=N<=150, 1<=M<=10,但 ...
- poj 2096Collecting Bugs
题目链接 poj 2096Collecting Bugs 题解 dp[i][j]表示已经找到i种bug,并存在于j个子系统中,要达到目标状态的天数的期望. 显然,dp[n][s]=0,因为已经达到目标 ...
- poj 2431 Expedition 贪心 优先队列 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=2431 题解 朴素想法就是dfs 经过该点的时候决定是否加油 中间加了一点剪枝 如果加油次数已经比已知最少的加油次数要大或者等于了 那么就剪 ...
随机推荐
- TP学习—第一天:框架的简单学习;创建应用;
一.框架目录文件的介绍 common 核心函数库目录 conf 框架的核心配置文件 lang 语言包目录 library 核心资源库目录 tpl 不用管,就是几个模板 Thin ...
- 使用php进行微信小程序图片安全验证
想用到微信公众平台的图片识别系统,结果报错{"errcode":41005,"errmsg":"media data missing hint: [x ...
- canvas可视化效果之内阴影效果
canvas可视化效果之内阴影效果 楔子 在之前的一个轨道交通可视化项目中,运用到了很多绘制技巧. 可以参考 之前的一篇文章 <利用canvas阴影功能与双线技巧绘制轨道交通大屏项目效果> ...
- Java 持久层框架之 MyBatis
MyBatis 简介 MyBatis 是一个基于 Java 的持久层框架,它内部封装了 JDBC,使开发者只需关注 SQL 语句本身,而不用再花费精力去处理诸如注册驱动.创建 Connection.配 ...
- Excel 多/整列(多/整行)移位操作
步骤1:创建测试数据 步骤2:把B列和C列进行移位操作(整列移位操作,多列移位操作方法一样) 选中B列,鼠标放到B列边缘地带,直到鼠标显示带有四个箭头方向为止,点击键盘shift键进行拖拽,拖拽时显示 ...
- pdf2swf 和pdf2html 使用命令详解
pdf2swf 将pdf文档转换为flash方式阅读,可以满足公式.图片的格式定义: pdf2htmlEX 将pdf文档转换为html方式阅读,有一下优点: 在HTML文件中精确显示原生文本 保持PD ...
- JavaSwing 船只停靠管理可视化(二)
JavaSwing 船只停靠管理可视化(一) JavaSwing 船只停靠管理可视化(二) JavaSwing 船只停靠管理可视化(三) JavaSwing 船只停靠管理可视化(四) JavaSwin ...
- 如何重新加载 Spring Boot 上的更改,而无需重新启动服务器?
这可以使用 DEV 工具来实现.通过这种依赖关系,您可以节省任何更改,嵌入式 tomcat将重新启动.Spring Boot 有一个开发工具(DevTools)模块,它有助于提高开发人员的生产力.Ja ...
- 美团在TIDB方面的实践
摘自-https://www.v2ex.com/t/508094 一.背景和现状 在美团,基于 MySQL 构建的传统关系型数据库服务已经难于支撑公司业务的爆发式增长,促使我们去探索更合理的数据存储方 ...
- 为什么Java中lambda表达式不能改变外部变量的值,也不能定义自己的同名的本地变量呢?
作者:blindpirate链接:https://www.zhihu.com/question/361639494/answer/948286842来源:知乎著作权归作者所有.商业转载请联系作者获得授 ...