考场想了 5.5 h,第一部分分死活打不出来,做到崩盘,现在重做,感觉自己就是一个sb,放学在地铁上一眼就会了。哎。

可以把一个要求看作一个长度为 \(m\) 的区间:\([l, l + m - 1]\),可以要求这段条件的充要条件是找到一种循环移位,每个墙恰好可以被那个工人挖。然后问题是用最少的区间覆盖完 \([0, n - 1]\)。

可以设一个 DP:

$f_i $:刷完前 \(i\) 个墙的最小要求次数。

  • 如果 \([i - m + 1, i]\) 可以刷,那么 \(f_i = \min_{i-m\le j <i}(f_j) + 1\)。
  • 否则 \(f_i\) 是正无穷。

这个东西显然是一个滑动窗口最值,用单调队列优化,我们现在的就要求快速判断 \([i - m + 1, i]\) 能不能刷。

设 \(len_{i, j}\) 为第 \(i\) 个墙,第 \(j\) 个人刷,最多可以循环移位向前延伸多少个。

对于一个 \(i\),枚举 \(C_i\) 颜色对应的所有的工人 \(u\),转移 \(len_{i, u} = len_{i - 1, (u - 1) \bmod m} + 1\)。

由于 \(\sum f(k)^2 \le 400000\),所以 \(f(k)\) 是 \(600\) 量级的,时间复杂度是 \(O(n \max(f(k)))\) 是可以过的。

但是空间不够,滚动数组就好了,但是还要保证转移的是 \(i - 1\) 次,所以每次转移赋值 \(g_{i \bmod 2, j} = i\),表示这个循环移位最后的位置是 \(i\)。转移判断上次的是不是 \(i - 1\) 就行了。

单调队列还有一些细节,比如正无穷不能扔进队列之类。

#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 100005, M = 50005, INF = 0x3f3f3f3f; int f[N], q[N], g[2][M], len[2][M]; vector<int> d[N]; int minimumInstructions(
int n, int m, int K, std::vector<int> c,
std::vector<int> a, std::vector<std::vector<int> > b) {
memset(f, 0x3f, sizeof f);
memset(g, -1, sizeof g);
for (int i = 0; i < K; i++) d[i].clear();
for (int i = 0; i < m; i++) {
for (int j = 0; j < a[i]; j++) {
d[b[i][j]].push_back(i);
}
}
int hh = 0, tt = -1;
for (int i = 0; i < n; i++) {
bool ok = false;
for (int j = 0; j < d[c[i]].size(); j++) {
int u = d[c[i]][j];
g[i & 1][u] = i, len[i & 1][u] = 1;
if (i && g[(i - 1) & 1][(u + m - 1) % m] == i - 1) len[i & 1][u] += len[(i - 1) & 1][(u + m - 1) % m];
if (len[i & 1][u] >= m) ok = true;
}
if (ok) {
while (hh <= tt && q[hh] < i - m) hh++;
if (i < m) f[i] = 1;
else if (hh <= tt) f[i] = f[q[hh]] + 1;
if (f[i] != INF) {
while (hh <= tt && f[q[tt]] >= f[i]) tt--;
q[++tt] = i;
}
}
}
return f[n - 1] == INF ? -1 : f[n - 1];
}

APIO2020 粉刷墙壁的更多相关文章

  1. Codeforces Round #198 (Div. 2)

    A.The Wall 题意:两个人粉刷墙壁,甲从粉刷标号为x,2x,3x...的小块乙粉刷标号为y,2y,3y...的小块问在某个区间内被重复粉刷的小块的个数. 分析:求出x和y的最小公倍数,然后做一 ...

  2. [SinGuLaRiTy] NOIP互测模拟赛

    [SinGuLaRiTy-1045] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 源文件名 输入输出文件 时间限制 内存限制 淘气的cch ...

  3. 【资料总结】html开发小实例

    目 录 第1章 1 HTML的基本标签 1 第2章 25 表格基础 25 第3章 53 表单和框架 53 第4章 77 CSS样式表 77 第5章 104 使用Dreamweaver制作网页 104 ...

  4. as well as

    一.as well 用法: 1.as well常用作状语,作“又:也”解,相当于too或also,常位于句末,无须用逗号与句子分开.如: I am going to London and my sis ...

  5. 【日语】日语单词N3_N4_N5

    日语单词N3_N4_N5 单 词 讲 解 あ行单词 ああ:0[副]那样.那种 例句:ああ言うことはしないほうがいい.那样的事情最好不做. 電車の窓からごみを棄てているああ言うことはしないほうがいい. ...

  6. 日语单词N3_N4_N5

    单 词 讲 解 あ行单词 ああ:0[副]那样.那种 例句:ああ言うことはしないほうがいい.那样的事情最好不做. 電車の窓からごみを棄てているああ言うことはしないほうがいい. 挨拶(あいさつ):① 寒暄 ...

  7. java设计模式3——建造者模式

    java设计模式3--建造者模式 1.建造者模式介绍: 建造者模式属于创建型模式,他提供了一种创建对象得最佳方式 定义: 将一个复杂对象的构建和与它的表示分离,使得同样的构建过程可以创建不同的表示 主 ...

  8. poj1821 Fence(dp,单调队列优化)

    题意: 由k(1 <= K <= 100)个工人组成的团队应油漆围墙,其中包含N(1 <= N <= 16 000)个从左到右从1到N编号的木板.每个工人i(1 <= i ...

  9. [LeetCode] Paint Fence 粉刷篱笆

    There is a fence with n posts, each post can be painted with one of the k colors. You have to paint ...

随机推荐

  1. netfilter内核态与用户态 通信 之 sockopt

    用户态与内核态交互通信的方法不止一种,sockopt是比较方便的一个,写法也简单.缺点就是使用 copy_from_user()/copy_to_user()完成内核和用户的通信, 效率其实不高, 多 ...

  2. linux 进程间通信 共享内存 shmat

    系统调用mmap()通过映射一个普通文件实现共享内存.系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信.也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件(这是通过shm ...

  3. Java 实例化接口或抽象类

    1. 实例化接口: 某一天,我们想通过反射调用一个类的方法,但发现方法参数中有一个接口,我们都知道接口不能被实例化,这该怎么办呢? 举例: public class TestLib { public ...

  4. 【进阶之路】Redis基础知识两篇就满足(一)

    导言 大家好,我是南橘,一名练习时常两年半的java练习生,这是我在博客园的第一篇文章,当然,都是要从别处搬运过来的,不过以后新的文章也会在博客园同步发布,希望大家能多多支持^_^ 这篇文章的出现,首 ...

  5. PHP 使用gd库给图片加图片水印,文字水印,并返回路径

    //图片水印 $mark_filename = './02.jpg'; //获取图片信息 $info = getimagesize($mark_filename); //获取图片的后缀 $type = ...

  6. 巧妙运用Camtasia 旅行Vlog轻松get

    旅行时,除了要欣赏当地的美丽风景.享受当地美食外,当然还要将旅行中的各种小细节记录下来.以前我们可能更多地使用相机拍照,现在呢,越来越多的人采用视频拍摄的方式制作Vlog.这种兼具影像与叙事的视频表现 ...

  7. 电子邮件怎么用EasyRecovery恢复,只需简单5步

    在日常工作中,我们常常会用电子邮件与上事.客户等协商工作事务.电子邮件快捷.方便,慢慢地成为我们工作中不可缺少的沟通工具之一. 然而使用的过程中,你会发现垃圾邮件也越积越多了,平时,我看到积压的垃圾邮 ...

  8. JS&Swift相互交互

    加载本地HTML文件       x         override func loadView() {    super.loadView()    let conf = WKWebViewCon ...

  9. recovery.sh

    #!/bin/bash source /etc/profile Time=`date +%F-%H-%M` Dir=/data/any.service.recovery if [ ! -d $Dir ...

  10. 配置Nginx 扩展实现图片剪裁

    在此之前需要安装ngx_http_image_filter_module,如果是采用的Docker的话可以看看我历史文章. 然后修改配置文件,增加几个location模块,配置如下,仅供参考 serv ...