题目大意

考虑一个 $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 状态还要满足转移的完备性。

所谓转移的完备性是指,从某一状态进行一次满足最优性的基本操作所到达的新状态必须能够被表示。

这里需要注意的是,从某个状态进行一个基本操作之后所能转移到的新状态可能不唯一(但一般是常数个)。

最优性条件往往用来减小在某个状态时需要考虑的基本操作的种类。

由「最优性」条件可知:

  1. 每次选取的子矩阵中至少要有一个 *。
  2. 从状态 $(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的更多相关文章

  1. Codeforces 903F Clear The Matrix(状态压缩DP)

    题目链接 Clear The Matrix 题意 给定一个$4 * n$的矩形,里面的元素为$'.'$或$'*'$.现在有$4$种正方形可以覆盖掉$'*'$,正方形的边长分别为$1,2,3,4$. 求 ...

  2. Clear The Matrix CodeForces - 903F (状压)

    大意: 给定4行的棋盘以及4种大小的正方形方块, 每种各有一定花费, 每次可以选一种方块放在棋盘上, 棋盘对应格子全变为'.', 求最少花费使得棋盘全部变成'.' 状压基本操作练习, 状态取12位, ...

  3. CodeForces 313C Ilya and Matrix

    Ilya and Matrix Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Su ...

  4. codeforces C. Ilya and Matrix 解题报告

    题目链接:http://codeforces.com/problemset/problem/313/C 题目意思:给定 4n 个整数(可以组成 2n × 2n 大小的矩阵),问通过对这些整数进行排列, ...

  5. 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 ...

  6. codeforces 486B.OR in Matrix 解题报告

    题目链接:http://codeforces.com/problemset/problem/486/B 题目意思:给出一个m行n列的矩阵B(每个元素只由0/1组成),问是否可以利用矩阵B,通过一定的运 ...

  7. Codeforces 1085G(1086E) Beautiful Matrix $dp$+树状数组

    题意 定义一个\(n*n\)的矩阵是\(beautiful\)的,需要满足以下三个条件: 1.每一行是一个排列. 2.上下相邻的两个元素的值不同. 再定义两个矩阵的字典序大的矩阵大(从左往右从上到下一 ...

  8. codeforces 495D Sonya and Matrix

    Since Sonya has just learned the basics of matrices, she decided to play with them a little bit. Son ...

  9. Codeforces 884E E. Binary Matrix

    题 OvO http://codeforces.com/contest/884/problem/E 884e 解 考虑并查集,每个点向上方和左方的点合并,答案即为1的总数减去需要合并的次数 由于只有1 ...

随机推荐

  1. 爬去酷狗top500的数据

    import requests from bs4 import BeautifulSoup import time headers={ #'User-Agent':'Nokia6600/1.0 (3. ...

  2. 发现知乎的一个Bug,并且我绕过了此Bug,沾沾自喜中...

    发现问题 在知乎点击修改头像,上传图片时发现一片空白.凭着程序员的直觉,第一反应时看下控制台是否有报错.果然发现如下: Refused to load the image 'data:image/jp ...

  3. CF Gym 100187D Holidays (数学,递推)

    题意:给n个元素,从n中选两个非空集合A和B.问有多少中选法? 递推: dp[n]表示元素个数为n的方案数,对于新来的一个元素,要么加入集合,要么不加入集合自成一个集合.加入集合有三种选择,A,B,E ...

  4. N17_判断树B是不是树A的子结构

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) package new_offer; /** * 输入两棵二叉树A,B,判断B是不是A的子结构.( ...

  5. 禁止DataGridView控件中添加和删除行

    实现效果: 知识运用: DataGridView控件的AllowUserToAddRows AllowUserDeleteRows和ReadOnly属性 实现代码: private void btn_ ...

  6. 队列的add与offer的区别

    两个方法都表示往队列里添加元素 但是当出现异常时,add方法抛出异常 而offer则返回的是false,就是啥事也没有,也不抛异常,也没有添加成功!

  7. SQLServer锁原理和锁的类型

    1.锁的用途 为了避免同时争夺数据库资源,将数据库加锁,只有拿到钥匙的用户才能使用: 2.锁的粒度 行锁(Row)--->页锁(Page)--->区锁(Partition 8个页)---- ...

  8. Xcode 的expression命令

    expression命令是执行一个表达式,并将表达式返回的结果输出,是LLDB调试命令中最重要的命令,也是我们常用的 p 和 po 命令的 鼻祖. 他主要有2个功能 (1) 执行表达式 举例:改变视图 ...

  9. 如何挂载一个镜像文件(how to mount an image file)

    如何挂载一个镜像文件(how to mount an image file) 08/16/2012master 4 Comments 在使用KVM或Xen虚拟化的情况下,经常需要使用镜像文件(imag ...

  10. robotframework的列表与字典

    这里以Get Element Size为例,Selenium2Library返回的是列表,AppiumLibrary返回的是字典. 列表用 ${width}获取:字典用 &{ui}[width ...