CF1990D Grid Puzzle 题解
DP 好题。考虑分析两种操作的性质,不难发现操作 \(1\) 至多只能涂白 \(4\) 个方格,而操作 \(2\) 可以涂白的方格取决于这一行的方格数,几乎无上限。 因此,从涂白的方格数考虑,对于黑色方格数量 \(\ge5\) 的一行,我们直接使用操作 \(2\) 涂白。注意黑色方格数量等于 \(4\) 的一行不一定直接使用操作 \(2\),因为无法比较两种操作哪个更优。
之后,考虑到剩余每行的黑色方格数很少,不会超过 \(4\),考虑动态规划。不难发现每次使用操作 \(1\) 左下角一定在第一列或者第三列,否则可以挪动证明一定不优。设状态 \(f[i][j]\) 表示第 \(i\) 行状态为 \(j\) 且前 \(i-1\) 行全部被覆盖的最小操作次数。若 \(j=0\),表示没有任何方格被覆盖;若 \(j=1\),表示第一、二行的方格被覆盖,即以这一行第一列为左下角进行一次操作 \(1\);若 \(j=2\),表示第三、四行的方格被覆盖,即以这一行第三列为左下角进行一次操作 \(1\);若 \(j=3\),表示所有方格被覆盖。初始时全为负无穷。
显然,对于黑色方格数量 \(\ge5\) 的一行或本来就没有黑色方格的一行,\(f[i][3]=0\)。
对于其他情况,我们把每个状态分别进行转移。
\]
\]
如果这一行没有任何方格被覆盖,为了满足定义前 \(i-1\) 行全部被覆盖,必须选取全部被覆盖的状态,即 \(f[i-1][3]\)。特别的,若 \(a[i-1]\le2\),状态 \(f[i-1][1]\) 也是完全覆盖。
\]
\]
以这一行第一列为左下角进行一次操作 \(1\),则也会覆盖上一行的第一、二列。因此,可以从 \(f[i-1][2]\) 的状态转移过来,这样上一行所有列都被覆盖。当然,也可以从 \(f[i-1][3]\) 转移。特别的,若 \(a[i-1]\le2\),从状态 \(f[i-1][0]\) 转移也是完全覆盖。
\]
同上,不过不需要考虑 \(a[i-1]\le2\) 的情况,因为没有影响。
\]
\]
\]
如果这一行所有方格被覆盖,那么上一行的状态可以任意选择。另外,也可以直接使用操作 \(2\),同 \(f[i][0]\) 的转移,此时应该选择 \(f[i-1][3]\) 进行转移。特别的,若 \(a[i-1]\le2\),状态 \(f[i-1][1]\) 也是完全覆盖。
最后,对于每段被 \(0\) 隔开的部分分别计算答案进行累加,并计算上最初操作 \(2\) 的贡献,即可解决问题。时间复杂度 \(O(n)\)。
#include <bits/stdc++.h>
using namespace std;
long long t,n,a[300000],f[300000][4];
int main()
{
scanf("%lld",&t);
while(t--)
{
long long ans=0;
scanf("%lld",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(a[i]>=5)ans++,a[i]=0;
}
for(int i=0;i<=n;i++)
for(int j=0;j<=3;j++)
f[i][j]=1e16;
f[0][3]=0,a[n+1]=0;
for(int i=1;i<=n;i++)
if(!a[i])f[i][3]=0;
for(int i=1;i<=n;i++)
if(a[i])
{
f[i][0]=min(f[i][0],f[i-1][3]);
if(a[i-1]<=2)f[i][0]=min(f[i][0],f[i-1][1]);
f[i][1]=min(f[i][1],min(f[i-1][3]+1,f[i-1][2]+1));
if(a[i-1]<=2)f[i][1]=min(f[i][1],f[i-1][0]+1);
f[i][2]=min(f[i][2],min(f[i-1][3]+1,f[i-1][1]+1));
f[i][3]=min(f[i][3],min(f[i-1][3]+2,min(f[i-1][2]+2,min(f[i-1][1]+2,f[i-1][0]+2))));
f[i][3]=min(f[i][3],f[i-1][3]+1);
if(a[i-1]<=2)f[i][3]=min(f[i][3],f[i-1][1]+1);
}
for(int i=1;i<=n;i++)
if(a[i]!=0&&a[i+1]==0)
{
long long k=min(f[i][3],min(f[i][2]+1,min(f[i][1]+1,f[i][0]+2)));
if(a[i]<=2)k=min(k,f[i][1]);
ans+=k;
}
printf("%lld\n",ans);
}
return 0;
}
CF1990D Grid Puzzle 题解的更多相关文章
- POJ1651:Multiplication Puzzle——题解
http://poj.org/problem?id=1651 题目大意:同“乘法游戏”,这里将乘法游戏的题面复制过来. 乘法游戏是在一行牌上进行的.每一张牌包括了一个正整数.在每一个移动中,玩家拿出一 ...
- POJ3678:Katu Puzzle——题解
http://poj.org/problem?id=3678 总觉得这题比例题简单. 设a为x取0的点,a+n为x取1的点. 我们还是定义a到b表示取a必须取b. 那么我们有: 当AND: 1.当c= ...
- ZOJ - 3781 Paint the Grid Reloaded 题解
题目大意: 给一个n*m的X O构成的格子,对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X—>O或O—>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色. 思路: 1. ...
- ZOJ 2836 Number Puzzle 题解
题面 lcm(x,y)=xy/gcd(x,y) lcm(x1,x2,···,xn)=lcm(lcm(x1,x2,···,xn-1),xn) #include <bits/stdc++.h> ...
- HDU 全国多校第四场 题解
题解 A AND Minimum Spanning Tree 参考代码: #include<bits/stdc++.h> #define maxl 200010 using namespa ...
- 【AtCoder】AGC029(A-E)
A - Irreversible operation 题解 把每个B后面的W个数累加起来即可 代码 #include <bits/stdc++.h> #define fi first #d ...
- 算法与数据结构基础 - 广度优先搜索(BFS)
BFS基础 广度优先搜索(Breadth First Search)用于按离始节点距离.由近到远渐次访问图的节点,可视化BFS 通常使用队列(queue)结构模拟BFS过程,关于queue见:算法与数 ...
- 20191028 Codeforces Round #534 (Div. 1) - Virtual Participation
菜是原罪. 英语不好更是原罪. \(\mathrm{A - Grid game}\) 题解 \(4 \times 4\) 的格子,两种放法. 发现这两种在一起时候很讨厌,于是强行拆分这个格子 上面 \ ...
- LRJ
//3-1 #define _CRT_SECURE_NO_WARNINGS #include <cstdio> int main() { int T; ]; scanf("%d& ...
- 【题解】AT2043 AND Grid
[题解]AT2043 AND Grid 我们考虑直接构造两个互补的图切分别联通的图,然后原图有的大家都有就构造完成了. #include<iostream> #include<cst ...
随机推荐
- Cookie,Session与Token
参考资料 水平有限,欢迎交流!仅做学习交流使用 一定要看,非常透彻![Cookie.Session.Token究竟区别在哪?如何进行身份认证,保持用户登录状态?] 黑马jwt详解 Javaweb程序设 ...
- gRPC 和传统 RPC 有啥不一样?一篇讲清楚!
现在大家做系统开发,都喜欢搞"微服务架构"--简单说就是把一个大系统拆成很多小服务,这样更灵活也更容易扩展.那这些服务之间怎么沟通呢?就得靠一种技术叫 RPC(远程过程调用).今天 ...
- DPDI online在线调度系统环境部署
DPDI online简介: DPDI Online 是一款基于Kettle的强大在线任务调度平台,凭借其高效与灵活性,专为调度和监控Kettle客户端生成的ETL任务而设计 DPDI online部 ...
- Ubuntu修改密码及密码复杂度策略设置方法
版本查看 cat /etc/issue cat /proc/version 内核查看 uname -a Ubuntu修改密码及密码复杂度策略设置方法 一.修改密码 1.修改普通用户密码 passwd ...
- 架构哲学与游戏工业化:策划x程序x抽象x复用x易用=降本增效
(一)前言 策划 x 程序 x 抽象 x 复用 x 易用 = 降本增效 公式为什么是乘法而不是加法? 如果是加法,任何一个维度的数据为0时结果可能还是正数:如果是乘法,任何一个维度数据都不能为0否则结 ...
- K8s进阶之Deployment的更新&回滚
更新概述 更新指的是对 Deployment 所管理应用的配置.镜像版本等进行修改并应用到集群中的过程.通过更新 Deployment,你能够实现应用功能的升级.修复漏洞.调整资源分配等操作. 更新触 ...
- 数据库问题之“字符编码问题 Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x8E\x81\xE7\x88...' for column 'product_name' at row 41”
1)表1和表2的产品名称[数据库字段]字符编译方式不一致 ①问题 org.springframework.jdbc.UncategorizedSQLException: Error updating ...
- 解决ZYNQ-7020开发板使用vitis编译uboot报错和无法正常调试的问题
整个学习过程是参考正点原子启明星开发板的2020.2版本嵌入式Linux开发指南,在学习uboot移植的时候遇到了问题. 新建工程和配置环境啥的和教程里都一样,就不罗嗦了,这里重点讲和教程不一样的地方 ...
- codeup之沙漏图形
Description 问题:输入n,输出正倒n层星号三角形.首行顶格,星号间有一空格,效果见样例 输入样例: 3 输出样例: * * * * * * * * * * * 数据规模 1<= n ...
- Longest Consecutive Sequence——LeetCode进阶路
原题链接https://leetcode.com/problems/longest-consecutive-sequence/ 题目描述 Given an unsorted array of inte ...