题目大意

考虑一个 $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 );

第二个函数声明中的返回值的类型 referencebitset 定义的一个 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. CF Gym 100463A (树状数组求逆序数)

    题意:给你一个序列,和标准序列连线,求交点数. 题解:就是求逆序对个数,用树状数组优化就行了.具体过程就是按照顺序往树状数组了插点(根据点的大小),因为第i大的点应该排在第i位,插进去的时候他前面本该 ...

  2. python 列表 字典转json

    一.Dictionary 转为JSON 将dict转为JSON,这里利用包json import jsonaItem = {}aItem["id"] = "2203&qu ...

  3. 《队长说得队》【Alpha】Scrum meeting 2

    项目 内容 这个作业属于哪个课程 >>2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 >>实验十二 团队作业8:软件测试与ALPHA冲刺 团队名称 ...

  4. echarts实现仪表盘(自己动起来,没有后端,顺便重温math.random

    let a = parseInt(Math.random() * (2 + 1), 10); let arr = []; arr.push(res[a]); let option = { toolti ...

  5. ☆☆☆Dojo中define和declare的结合使用

    在原生的js中是不可以创建类的,没有class这个关键字,但是在dojo中,dojo自定义了一个模块叫做dojo/_base/declare,用这个模块我们可以创建自己的类,实现面向对象编程. 单继承 ...

  6. iOS开发遇到的坑之六--使用cocopods管理第三方库时,编译出现Library not found for -lPods问题的解决办法

    在项目中有时候会遇到Library not found for -lPods(这里的IPods指的是你具体的第三方库)的问题 出现这个错误的原因是:xcode在编译的时候找不到这个库,从而导致项目无法 ...

  7. (转发)IOS动画中的枚举UIViewAnimationOptions

    若本帖转自(博客园·小八究):http://www.cnblogs.com/xiaobajiu/p/4084747.html 可怜目前天朝搜不到什么有价值的东西方便学习,在这里方便初学者. 首先这个枚 ...

  8. OC和C++的混用2

    苹果的Objective-C编译器允许用户在同一个源文件里自由地混合使用C++和Objective-C,混编后的语言叫Objective-C++.有了它,你就可以在Objective-C应用程序中使用 ...

  9. Mac下快捷键的符号所对应的按键

  10. Python爬虫系列-Selenium详解

    自动化测试工具,支持多种浏览器.爬虫中主要用来解决JavaScript渲染的问题. 用法讲解 模拟百度搜索网站过程: from selenium import webdriver from selen ...