Codeforces 903F Clear the Matrix
题目大意
考虑一个 $4$ 行 $n$ ($4\le n\le 1000$)列的矩阵 $f$,$f$ 中的元素为 * 或 . 。
对 $f$ 进行若干次如下变换:
将一个 $k\times k$($1\le k \le 4$)的子矩阵中的元素全部替换为 .,代价为 $a_k$( $1 \le a_k \le 1000$)。
求将 $f$ 中的元素全置为 * 所需的最小代价。
分析
很容易想到的做法是「状压 DP」。
Codeforces 上把「状态压缩」这个方法称作「bitmasks」。我从 Codeforces 的题解上读到,这种「铺地砖」类型的状压 DP, 英文可以叫做「DP on broken profile」。
将矩阵 $f$ 的列编号为 0 到 $n-1$ 。
DP 状态为
$c_{i,s}$:「第 0 列到第 $i-1$ 列全部置为
.,第 $i$ 到第 $\min(i+2,n-1)$ 列的状态为 $s$ ,而不管其余的列的状态如何」所需的最小代价。
如此设计 DP 状态考虑的是从左到右选取子矩阵做替换的过程。
这个 DP 状态是比较容易想到的,重点讨论如何转移:
一般而言,DP 状态的转移要满足原子性。
所谓原子性是指,从状态 $S$ 转移到状态 $T$ 所经过的操作(或称「变换」)必须是一个不可再分的基本操作。在有的问题中(比如这道题)「不做任何操作」也是一种基本操作。
当然,从状态 $S$ 经过多个基本操作也可能到达状态 $T$;但是在构造状态转移方程时,我们只考虑单步转移。
这个问题中的基本操作就是选取某个子矩阵进行替换或者不做替换。
此外, DP 状态还要满足转移的完备性。
所谓转移的完备性是指,从某一状态进行一次满足最优性的基本操作所到达的新状态必须能够被表示。
这里需要注意的是,从某个状态进行一个基本操作之后所能转移到的新状态可能不唯一(但一般是常数个)。
最优性条件往往用来减小在某个状态时需要考虑的基本操作的种类。
由「最优性」条件可知:
- 每次选取的子矩阵中至少要有一个
*。 - 从状态 $(i,s)$ 转移时,所选的子矩阵的最左一列必须是第 $i$ 列。
经过上述分析,不难得出转移方法
枚举在状态 $(i,s)$ 时可进行的操作,计算转移到的新状态 $(i', s')$ ,更新「新状态」的 DP 值(即最小代价)。
这个问题中,「转移到的新状态」可能是两个。
容易疏忽的是:
对于状态 $(i,s)$,若第 $i$ 行全为 .,那么不经任何替换即可转移到状态 $(i+1, s')$;其中 $s'$ 表示 $i+1$ 列到 $\min(i+3,n-1)$ 列当前的状态。
实现细节
对于状压 DP,在进行状态转移时,用 bitset 取代位运算,实现起来更方便。
通过 bitset 提供的成员函数 to_ulong() 或者 to_ullong() 可以很方便地把状态压缩到一个整数里,作为 DP 数组的下标。
bitset 还可以用 >> 算符以 01 串的格式输出,低位在右,高位在左。
注意:在索引时,第 0 位是最低位。
另外,bitset 作为 sequential container 提供了 [] 运算符。
[] 有两个版本(重载),其返回值可以是 lvalue,也可以是 rvalue.
constexpr bool operator[]( std::size_t pos ) const;
和
reference operator[]( std::size_t pos );
第二个函数声明中的返回值的类型 reference 是 bitset 定义的一个 proxy class 。
reference 类型支持的操作符只有:
operator=
operator bool
operator ~
flip
Codeforces 903F Clear the Matrix的更多相关文章
- Codeforces 903F Clear The Matrix(状态压缩DP)
题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为$'.'$或$'*'$.现在有$4$种正方形可以覆盖掉$'*'$,正方形的边长分别为$1,2,3,4$. 求 ...
- Clear The Matrix CodeForces - 903F (状压)
大意: 给定4行的棋盘以及4种大小的正方形方块, 每种各有一定花费, 每次可以选一种方块放在棋盘上, 棋盘对应格子全变为'.', 求最少花费使得棋盘全部变成'.' 状压基本操作练习, 状态取12位, ...
- CodeForces 313C Ilya and Matrix
Ilya and Matrix Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Su ...
- codeforces C. Ilya and Matrix 解题报告
题目链接:http://codeforces.com/problemset/problem/313/C 题目意思:给定 4n 个整数(可以组成 2n × 2n 大小的矩阵),问通过对这些整数进行排列, ...
- Educational Codeforces Round 40 C. Matrix Walk( 思维)
Educational Codeforces Round 40 (Rated for Div. 2) C. Matrix Walk time limit per test 1 second memor ...
- codeforces 486B.OR in Matrix 解题报告
题目链接:http://codeforces.com/problemset/problem/486/B 题目意思:给出一个m行n列的矩阵B(每个元素只由0/1组成),问是否可以利用矩阵B,通过一定的运 ...
- Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组
题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...
- codeforces 495D Sonya and Matrix
Since Sonya has just learned the basics of matrices, she decided to play with them a little bit. Son ...
- Codeforces 884E E. Binary Matrix
题 OvO http://codeforces.com/contest/884/problem/E 884e 解 考虑并查集,每个点向上方和左方的点合并,答案即为1的总数减去需要合并的次数 由于只有1 ...
随机推荐
- 关于日志造成的频繁的IO
记录日志可能消耗大量的IO [Q] 每次写入都是一个IO操作 即使是同一个文件 两次写入也要打开两次IO操作 [F] 设想有这样一个扩展 把php中要记录的日志 用文件名 和 内容的方式记录在内存中 ...
- SAP CRM Survey调查问卷的存储模型
数据库表CRM_SVY_DB_SVS,通过如下的函数CRM_SVY_DB_SVS_CREATE插入: 可以通过指定的创建者和创建时间很容易查找到特定的Survey: 调查问卷的答案明细以XML的格式存 ...
- Memcache使用基础
Memcached的特点: 协议简单 基于libevent的事件处理 内置内存存储方式 memcached不互相通信的分布式 1.协议简单: 使用简单的基于 ...
- linux交换分区调整
SWAP就是LINUX下的虚拟内存分区,它的作用是在物理内存使用完之后,将磁盘空间(也就是SWAP分区)虚拟成内存来使用.它和Windows系统的交换文件作用类似,但是它是一段连续的磁盘空间,并且 ...
- Linux curl命令中,HTTP 302处理
在Linux中使用curl命令时,偶尔会遇到一些URL跳转到新的URL,即HTTP中的3XX(redirection,重定向 ). $curl -s -I $URL > log 这时在返回的报文 ...
- 【转】Matlab的regionprops详解
matlab函数_连通区域 1. matlab函数bwareaopen──删除小面积对象格式:BW2 = bwareaopen(BW,P,conn)作用:删除二值图像BW中面积小于P的对象,默认情况下 ...
- 【线段树 扫描线 二维数点】loj#6276. 果树
路径计数转成二维数点很妙啊 题目描述 NiroBC 姐姐是个活泼的少女,她十分喜欢爬树,而她家门口正好有一棵果树,正好满足了她爬树的需求. 这颗果树有 $N$ 个节点,标号 $1 \ldots N$ ...
- Redis错误解决:(error) MISCONF Redis is configured to save RDB snapshots
刚开始学习使用redis数据库,在执行删除命令时,提示了我这么一个错误: 错误提示 (error) MISCONF Redis is configured to save RDB snapshots, ...
- Linux-Mysql8.0
Mysql8.0.12 基本操作 解释 命令 安装服务端 yum install mysql-community-server 启动 service mysqld start/restart 停止 s ...
- python入门:BREAK 的用法 跳当前循环后,不再执行下面代码块
#!/urs/bin/env python # -*- coding:utf-8 -*- # BREAK 的作用 跳当前循环后,不再执行下面代码块 while True: ') break ') #w ...