APIO2020 粉刷墙壁 题解
P6764 [APIO2020]粉刷墙壁
VP的时候打满了63分,没想到正解竟是两个暴力的合体/dk
首先,在这里定义粉刷匠的下家关系:
对于粉刷匠 i , j i,j i,j,如果 i + 1 = j i+1=j i+1=j 或者 i = m , j = 1 i=m,j=1 i=m,j=1,则称 j j j 是 i i i 的下家
6分: f ( k ) ≤ 1 f(k)\le 1 f(k)≤1
可以发现,对于每一次操作,要么所有的粉刷匠都刷一格,要么都不刷。所以,我们尝试对于每一格,是否存在一种粉刷顺序使得可以刷完后面的 m m m 格。
设 f i f_i fi 表示从第 i i i 格开始刷最多可以往后刷多远(包括第 i i i 格)
转移方程: f i = f i + 1 + 1 f_i=f_{i+1}+1 fi=fi+1+1
如果 i + 1 i+1 i+1 不是 i i i 的下家,则 f i = 1 f_i=1 fi=1
时间复杂度 O ( n ) \mathcal O(n) O(n)
51分
上一档部分分考虑的是每个格子只能由一个粉刷匠刷,现在我们考虑把问题扩展到多个粉刷匠
设 f i , j f_{i,j} fi,j 表示位置 i i i 由编号为 j j j 的粉刷匠来刷,最多可以往后刷多少格(包括第 i i i 格)
转移方程: f i , j = f i + 1 , k f_{i,j}=f_{i+1,k} fi,j=fi+1,k,这里 k k k 为 j j j 的下家
如果粉刷匠 j j j 不能刷第 i i i 格,则 f i , j = 0 f_{i,j}=0 fi,j=0
时空复杂度 O ( n m ) \mathcal O(nm) O(nm)
100分
观察上面51分的做法,可以发现他进行了许多冗余的操作:
对于位置 i i i,所有不能刷第 i i i 格的粉刷匠都被访问了一遍。
那么,我们可以预处理出每个位置可能被哪些粉刷匠刷,并且在转移时只转移可以刷第 i i i 格的粉刷匠
这样,时间复杂度就变成了 O ( ∑ f ( k ) ) \mathcal O(\sum f(k)) O(∑f(k))
注意这里的空间也也需要优化,可以使用滚动数组或者用 map
优化掉后一维,代码中采用的是后者
#include <vector>
#include<map>
using namespace std;
const int Maxn=1e5+10;
map <int,int> f[Maxn];
vector <int> c[Maxn],b[Maxn];
int a[Maxn];
bool flag[Maxn];
int n,m,k;
int minimumInstructions(int N, int M, int K, std::vector<int> C,std::vector<int> A, std::vector<std::vector<int>> B)
{n=N,m=M,k=K;for(int i=1;i<=n;++i)a[i]=C[i-1]+1;for(int i=1;i<=m;++i){int tmp=A[i-1];for(int j=0;j<tmp;++j)b[B[i-1][j]+1].push_back(i);}for(int i=1;i<=n;++i)c[i]=b[a[i]];for(int i=n;i;--i)for(int j=0;j<c[i].size();++j){int x=c[i][j];int y=c[i][j]+1;if(y>m)y=1;f[i][x]=1;if(i+1<=n)f[i][x]=f[i+1][y]+1;f[i][x]=min(f[i][x],m);if(f[i][x]==m)flag[i]=1;}int ret=0;for(int i=n-m+1;i;--i){if(!flag[i])return -1;++ret;if(i==1)break;int tmp=max(i-m,1);for(int j=tmp;j<i;++j)if(flag[j] || j==i-1){i=j+1;break;}}return ret;
}
APIO2020 粉刷墙壁 题解相关推荐
- 【NOIP2013模拟】粉刷匠 题解代码
原题 Description 赫克托是一个魁梧的粉刷匠,而且非常喜欢思考= = 现在,神庙里有N根排列成一直线的石柱,从1到N标号,长老要求用油漆将这些石柱重新粉刷一遍.赫克托有K桶颜色各不相同的油漆 ...
- bzoj 1296 洛谷4158 [SCOI2009]粉刷匠 题解
题意简述 一个 n × m n\times m n×m的矩阵,每个位置珂能是粉色(0表示)或者是蓝色(1表示),然后你珂以对同一行里连续一段长度的区间染上一种颜色(覆盖型),你能染 t t t次,每次 ...
- 【编程题】网易游戏社招编程题题解
网易游戏社招编程题题解 题目1:地形最低值的和 题目2:最少花的钱数 题目3:粉刷墙壁 题目4:被n到达的数 题目1:地形最低值的和 题目描述:在一个 n × m n \times m n×m的地图中 ...
- nefu 984 我是一个粉刷匠
其实刚开始我也没想出来,后来看了其他大神的描述终于明白了,其实就是把每一行每一列遍历一遍. description 小明最近在粉刷墙壁,他家的墙壁正好贴了8*8块瓷砖,可惜这些瓷砖都是白色的,小 ...
- bzoj1296 [SCOI2009]粉刷匠
题目链接:bzoj1296 题目大意: windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上 ...
- APIO2020游记
Day 0 甚至不记得第二天要考 APIO 了,键盘一周没动了--还好咕咕咕的 CCF 因为账号密码忘记发了引起热议才提醒了我. Day 1 早上睡到太阳能晒到床上,抓了点干粮,匆匆忙忙跑到学校. 尝 ...
- 读后感与机翻《理解工具:面向任务的对象建模、学习和识别》
以下是研究朱松纯FPICU概念中P(physics)的第一篇论文记录: 目录 读后感: 作者干了什么事? 作者怎么做的? 效果怎么样? 局限性 摘要 1 介绍 2 面向任务的对象表示 2.1 三维空间 ...
- java web开发初学_2018年学习Web开发的绝对初学者指南
java web开发初学 This post was originally published on Coder-Coder.com. 该帖子最初发布在Coder-Coder.com上 . If yo ...
- 刷墙(左蓝右红或同一色)
最近小明搬到了新家,他正在粉刷墙壁,但是不幸的是他粉刷的墙壁并不理想.他的墙壁是一个长度为 n 的格子,每个格子用0表示红色,用1表示蓝色.现在墙壁是一个非常混乱的颜色.他想将墙壁涂成左边全是蓝色右边 ...
最新文章
- 运维进阶——CIFS文件系统共享
- 你面试稳了!通关LeetCode刷题完整攻略,省时又高效
- WWDC2014:留给微软的时间不多了!
- js插件---webuploader 使用(lavarel中使用)
- matlab里面板有什么作用,MATLAB轻松享受GPU的强大功能
- sql 计算两个小数乘积_数学家是如何计算出π的?
- 【GDKOI2004】使命的召唤
- windows下python虚拟环境virtualenv安装和使用
- kubeadm单集群部署k8s1.15.1flannel网络
- vs2019 缺android sdk,VS2019由于缺少NuGet Microsoft.NET.Sdk.Functions程序包而无法加载项目,但也无法添加此程序包(示例代码)...
- 错误:this is incompatible with sql_mode=only_full_group_by
- matlab pdist如何实现,在MATLAB版本7中相当于pdist2
- python怎样填充颜色_python中如何给图形填充颜色
- java 限流熔断_SpringCloud-Alibaba-Sentinel服务降级,热点限流,服务熔断
- java 框架介绍------权限框架
- 网络工程职业规划【转载】
- c#文件排序和文件夹排序
- 华为ensp_三层交换
- 微信小程序分享朋友圈 详细教程及注意事项
- windows打不开应用商店,edge浏览器不能登录同步