LOJ 2372 -「CEOI2002」臭虫集成电路公司(轮廓线 dp)
u1s1 似乎这题全网无一题解?那就由我来写篇题解造福人类罢(伦敦雾
首先看这数据范围,一脸状压。考虑到每一层的状态与上面两层有关,因此每层转移到下一层的有用信息只有两层,需要用三进制保存状态。不过如果我们按照套路对行的状态进行压缩,我们就需要用这个状态进行 \(dfs\) 枚举各种放的情况并更新答案,实现起来会比较繁琐。因此这里采用另一种做法。
我们考虑一格格填 instead of 一行行填,具体来说,我们先考虑第一行第一列的状态,考虑完之后再考虑第一行第二列、第一行第三列……第一行考虑完之后再考虑第二行,以此类推,显然转移过的格子和没转移过的格子被一个折线分成了两半。这个折线我们称其为轮廓线。
考虑状压轮廓线上方格子的状态,具体来说,我们记 \(dp_{x,y,S}\) 表示当前考虑到第 \(x\) 行第 \(y\) 列,\(S\) 是一个三进制数,描述了轮廓线上方格子的状态,其中 \(S\) 的 \(3^{j-1}\) 位为 \(0\) 表示第 \(j\) 列轮廓线上方有 \(0\) 个空格子,为 \(1\) 表示第 \(j\) 列轮廓线上方有 \(1\) 个空格子,为 \(2\) 表示第 \(j\) 列轮廓线上方有 \(2\) 个空格子,那么有转移:
- 若 \(x=1\) 那显然 \(dp_{x,y,S}=0\)
- 如果 \(S\) 的 \(3^{y-1}\) 位 \(\ge 1\),那么格子 \((x,y)\) 被强制留空,我们就只能从 \((x,y)\) 前一个格子 \((x',y')\) 转移过来,第 \(y\) 列轮廓线向上移了一格,第 \(y\) 列上方空格子的个数也就少了 \(1\),故 \(dp_{x,y,S}=dp_{x',y',S-3^{y-1}}\)。
- 否则 \(dp_{x,y,S}\) 可能有三种转移方式:
- \((x,y)\) 留空,\(dp_{x,y,S}=dp_{x',y',S}\),其中 \((x',y')\) 为 \((x,y)\) 前一个被访问的格子。
- 以 \((x,y)\) 为右下角横着(左上角为 \((x-1,y-2)\))放一个 \(2\times 3\) 的矩形,\(dp_{x,y,S}=dp_{x',y',S+3^{y-1}+3^{y-2}+3^{y-3}}+1\),其中 \((x',y')\) 为 \((x,y)\) 倒推三格的格子,这种情况转移的前提条件是 \(S\) 中 \(3^{y-1},3^{y-2},3^{y-3}\) 位都是 \(0\),并且以 \((x,y)\) 为右下角,\((x-1,y-2)\) 为左上角的矩形不含特殊格子。
- 以 \((x,y)\) 为右下角竖着(左上角为 \((x-2,y-1)\))放一个 \(3\times 2\) 的矩形,\(dp_{x,y,S}=dp_{x',y',S+2\times 3^{y-1}+2\times 3^{y-2}}+1\),其中 \((x',y')\) 为 \((x,y)\) 倒推两格的格子,这种情况转移的前提条件是 \(S\) 中 \(3^{y-1},3^{y-2}\) 位都是 \(0\),并且以 \((x,y)\) 为右下角,\((x-2,y-1)\) 为左上角的矩形不含特殊格子。
就这样转移就行了,时空复杂度均为 \(nm3^m\)。由于此题空间限制较小,需滚动数组优化转移,需记录当前点往前 \(4\) 格的 \(dp\) 值。这样空间复杂度就能降到 \(3^m\) 了。
const int MAXN=150;
const int MAXS=6e4;
const int MAXM=10;
int n,m,k,dp[5][MAXS+5],pw3[MAXM+5];bool bad[MAXN+5][MAXM+5];
int getbit(int x,int y){return x/pw3[y]%3;}
void solve(){
scanf("%d%d%d",&n,&m,&k);memset(bad,0,sizeof(bad));memset(dp,0,sizeof(dp));
for(int i=1,x,y;i<=k;i++) scanf("%d%d",&x,&y),bad[x][y]=1;
int cur=0;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){
cur=(cur+1)&3;
int can_hor=(i>=2&&j>=3&&!bad[i][j]&&!bad[i-1][j]&&!bad[i][j-1]&&!bad[i-1][j-1]&&!bad[i][j-2]&&!bad[i-1][j-2]);
int can_ver=(i>=3&&j>=2&&!bad[i][j]&&!bad[i-1][j]&&!bad[i-2][j]&&!bad[i][j-1]&&!bad[i-1][j-1]&&!bad[i-2][j-1]);
// printf("%d %d %d %d\n",i,j,can_hor,can_ver);
for(int s=0;s<pw3[m];s++){
if(i==1) dp[cur][s]=0;
else if(getbit(s,j-1)>0) dp[cur][s]=dp[(cur-1)&3][s-pw3[j-1]];
else{
dp[cur][s]=dp[(cur-1)&3][s];
if(can_hor&&getbit(s,j-2)==0&&getbit(s,j-3)==0)
chkmax(dp[cur][s],dp[(cur-3)&3][s+pw3[j-1]+pw3[j-2]+pw3[j-3]]+1);
if(can_ver&&getbit(s,j-2)==0)
chkmax(dp[cur][s],dp[(cur-2)&3][s+2*pw3[j-1]+2*pw3[j-2]]+1);
}
// printf("%d %d %d %d\n",i,j,s,dp[cur][s]);
}
} printf("%d\n",dp[cur][0]);
}
int main(){
pw3[0]=1;for(int i=1;i<=MAXM;i++) pw3[i]=pw3[i-1]*3;
int qu;scanf("%d",&qu);while(qu--) solve();
return 0;
}
LOJ 2372 -「CEOI2002」臭虫集成电路公司(轮廓线 dp)的更多相关文章
- LOJ 3089 「BJOI2019」奥术神杖——AC自动机DP+0/1分数规划
题目:https://loj.ac/problem/3089 没想到把根号之类的求对数变成算数平均值.写了个只能得15分的暴力. #include<cstdio> #include< ...
- LOJ 2547 「JSOI2018」防御网络——思路+环DP
题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...
- LOJ 3056 「HNOI2019」多边形——模型转化+树形DP
题目:https://loj.ac/problem/3056 只会写暴搜.用哈希记忆化之类的. #include<cstdio> #include<cstring> #incl ...
- loj#2071. 「JSOI2016」最佳团体
题目链接 loj#2071. 「JSOI2016」最佳团体 题解 树形dp强行01分规 代码 #include<cstdio> #include<cstring> #inclu ...
- Loj #2192. 「SHOI2014」概率充电器
Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Loj #3096. 「SNOI2019」数论
Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...
- Loj #3093. 「BJOI2019」光线
Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...
- Loj #3089. 「BJOI2019」奥术神杖
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...
- Loj #2542. 「PKUWC2018」随机游走
Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...
随机推荐
- C/C++ 数据类型 表示最大 最小数值 探讨
C/C++中存储数字格式有整型和浮点型 字符型数据本质上也是以整型存储 整型 对于整型数据,最大值最小值很好计算 先确定对应数据型在本地所占用的字节数,同一数据型由于系统或者编译器的不同,所占字节不同 ...
- git常用的一些简单命令
1.如果一个文件被修改了,但是还没有使用 git add 命令,此时想取消这次修改,需要执行的命令如下: git checkout -- 文件名 2.如果一个文件执行了 git add ,此时想取消这 ...
- c语言编程基础入门必备知识
数据类型 基本数据类型 类型名称说明char字符类型存放字符的ASCII码int整型存放有符号整数short短整型存放有符号整数long长整型存放有符号整数long long存放有符号整数float单 ...
- STM32学习笔记之核心板PCB设计
PCB设计流程 PCB规则设置 设计规则的单位跟随画布属性里设置的单位,此处单位是mil.导线线宽最小为10mil;不同网络元素之间最小间距为8mil;孔外径为24mil,孔内径为12mil;线长不做 ...
- 计算机网络传输层之TCP协议(tcp协议特点、tcp报文段首部格式、tcp连接建立---三次握手、tcp连接释放---四次握手)
文章转自:https://blog.csdn.net/weixin_43914604/article/details/105516090 学习课程:<2019王道考研计算机网络> 学习目的 ...
- JAVA笔记12__字节、字符缓冲流/打印流/对象流/
/** * !!:以后写流的时候一定要加入缓冲!! * 对文件或其它目标频繁的读写操作,效率低,性能差. * 缓冲流:好处是能更高效地读写信息,原理是将数据先缓冲起来,然后一起写入或读取出来. * * ...
- 第01课 OpenGL窗口(3)
接下来的代码段创建我们的OpenGL窗口.我花了很多时间来做决定是否创建固定的全屏模式这样不需要许多额外的代码,还是创建一个容易定制的友好的窗口但需要更多的代码.当然最后我选择了后者.我经常在EMai ...
- oracle 数据库修改端口号1521
1.关闭监听 2.修改配置文件,port=1933 #vi $ORACLE_HOME/network/admin/listener.ora 3.登录并查看local_listener参数,因为使用的是 ...
- 攻防世界Web之fakebook
打开题目,得到一个网页,包含一个表格.两个按钮. 习惯性先查看网页源码,但没发现有效信息. <!doctype html> <html lang="ko"> ...
- Piakchu之RCE漏洞
一.Ping(远程系统命令执行) 首先正常输入一个ip,查看页面的返回值.发现有乱码,但是能看出执行了ping命令. 查看源代码,可以看到只是对操作系统进行了判断,而对输入内容是否为ip地址并没有判断 ...