题面传送门

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)的更多相关文章

  1. LOJ 3089 「BJOI2019」奥术神杖——AC自动机DP+0/1分数规划

    题目:https://loj.ac/problem/3089 没想到把根号之类的求对数变成算数平均值.写了个只能得15分的暴力. #include<cstdio> #include< ...

  2. LOJ 2547 「JSOI2018」防御网络——思路+环DP

    题目:https://loj.ac/problem/2547 一条树边 cr->v 会被计算 ( n-siz[v] ) * siz[v] 次.一条环边会被计算几次呢?于是去写了斯坦纳树. #in ...

  3. LOJ 3056 「HNOI2019」多边形——模型转化+树形DP

    题目:https://loj.ac/problem/3056 只会写暴搜.用哈希记忆化之类的. #include<cstdio> #include<cstring> #incl ...

  4. loj#2071. 「JSOI2016」最佳团体

    题目链接 loj#2071. 「JSOI2016」最佳团体 题解 树形dp强行01分规 代码 #include<cstdio> #include<cstring> #inclu ...

  5. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  6. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  7. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  8. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  9. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

随机推荐

  1. JavaScript05

    显示和隐藏 元素的显示和隐藏 元素display属性可控制元素的显示和隐藏,先获取元素对象,再通过点语法调用style对象中的display属性 语法格式: 元素.style.display='non ...

  2. 【UE4】GAMES101 图形学作业5:光线与物体相交(球、三角面)

    总览 在这部分的课程中,我们将专注于使用光线追踪来渲染图像.在光线追踪中最重要的操作之一就是找到光线与物体的交点.一旦找到光线与物体的交点,就可以执行着色并返回像素颜色. 在这次作业中,我们要实现两个 ...

  3. 【UE4 C++】学习笔记汇总

    UE4 概念知识 基础概念--文件结构.类型.反射.编译.接口.垃圾回收.序列化[导图] GamePlay架构[导图] 类的继承层级关系[导图] 反射机制 垃圾回收机制/算法 序列化 Actor 的生 ...

  4. [源码解析] Pytorch 如何实现后向传播 (1)---- 调用引擎

    [源码解析] Pytorch 如何实现后向传播 (1)---- 调用引擎 目录 [源码解析] Pytorch 如何实现后向传播 (1)---- 调用引擎 0x00 摘要 0x01 前文回顾 1.1 训 ...

  5. [软工顶级理解组] Beta阶段事后分析

    目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 质量提高 会议截图 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰 ...

  6. BUAA 2020 软件工程 提问回顾与个人总结

    BUAA 2020 软件工程 提问回顾与个人总结 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾 ...

  7. [CPP] 类的内存布局

    本文可以解决下面 3 个问题: 以不同方式继承之后,类的成员变量是如何分布的? 虚函数表及虚函数表指针,在可执行文件中的位置? 单一继承.多继承.虚拟继承之后,类的虚函数表的内容是如何变化的? 在这里 ...

  8. 21.6.23 test

    省选 模拟赛 今天考的是一套题目背景和描述会被[数据删除]的模拟赛. 犯了几个傻逼错. \(T1\) 把两种情况的概率看反了,写的暴力.\(35->5\) pts. \(T2\) 以为想到了正解 ...

  9. 国产Linux服务器-Jexus的初步使用

    题记:年末研究了一些关于Net跨平台的东西,没错,就是Jexus,就是Windows下面的IIS. 官网:https://www.jexus.org/ 先看看官网的解释再说其他的问题,Jexus就是L ...

  10. 2021 ICPC Gran Premio de Mexico 2da Fecha部分题题解

    前面的水题,在队友的配合下,很快就拿下了,剩下几道大毒瘤题,一直罚座三个小时,好让人自闭...但不得不说,这些题的质量是真的高! H. Haunted House 首先看这个题,大眼一扫,觉得是某种数 ...