题目大意:有一个长度为$2\times 10^5$的板,有$n(n\leqslant 10^5)$个格子$a_1,\dots,a_n$有布丁怪兽,一开始连续的怪兽算一个怪兽,有$m(m\leqslant 2000)$个特殊点$b_1,\dots,b_n$,你可以向左或向右移动怪兽,它会在碰到第一怪兽时停下,并成为一个怪兽。最左边和最右边的怪兽向两边移动会掉出板。问最多可以让布丁怪兽压到几个特殊点。

题解:先把连续的布丁怪兽看做长度个不同的怪兽,令$f_i$表示前$i$个怪兽最多可以覆盖多少个点,$g_i$表示前$i$个怪兽且第$i$个怪兽不动可以覆盖最多的点,$sum_{l,r}$表示$[l,r]$中特殊点个数

设当前转移坐标为$a_i$

1. 这个位置向左移,那么枚举$b_j$满足$b_j\leqslant a_i$,要覆盖区间$[b_j,a_i]$,就需要另外的$len=a_i-b_j$个怪兽,则

$$
g_i=\max\{g_i,f_{i-len-1}+sum_{b_j,a_i}\}
$$

2. 这个位置向右移,那么枚举$b_j$满足$b_j\geqslant a_i$,要覆盖区间$[a_i,b_j]$,需要另外$len=b_j-a_i$个怪兽,则

$$
f_{i+len}=\max\{f_{i+len},g_i+sum_{a_i+1,b_j}\}
$$

3. 这个位置不动,则
$$
f_i=\max\{f_i,g_i,f_{i-1}+sum_{a_i,a_i}\}\\
g_i=\max\{g_i,f_{i-1}+sum_{a_i,a_i}\}
$$

因为最开始怪兽有连续的,所以记录每个布丁怪兽的左端点和右端点,移动的时候将一整个怪兽移动即可

卡点:$f_i$没有用$g_i$更新,$g_i$使用了$g_{i-1}$来转移导致调了很久

C++ Code:

#include <cstdio>
#include <iostream>
#include <algorithm>
const int maxn = 1e5 + 10;
#define chkmax(a, b) (a = std::max(a, b)) int n, m;
int a[maxn], b[maxn], L[maxn], R[maxn];
int s[200010], f[maxn], g[maxn];
inline int sum(int a, int b) { return s[b] - s[a - 1]; }
inline int sum(int a) { return s[a] - s[a - 1]; } int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
std::cin >> n >> m;
for (int i = 1; i <= n; ++i) std::cin >> a[i];
for (int i = 1; i <= m; ++i) std::cin >> b[i], ++s[b[i]];
for (int i = 1; i <= 200000; ++i) s[i] += s[i - 1];
std::sort(a + 1, a + n + 1), std::sort(b + 1, b + m + 1);
a[0] = -20040826, a[n + 1] = 20040826;
for (int i = 1; i <= n; ++i)
if (a[i] != a[i - 1] + 1) L[i] = i;
else L[i] = L[i - 1];
for (int i = n; i; --i)
if (a[i] != a[i + 1] - 1) R[i] = i;
else R[i] = R[i + 1]; for (int i = 1; i <= n; ++i) {
chkmax(f[i], f[i - 1] + sum(a[i]));
chkmax(g[i], f[i - 1] + sum(a[i]));
for (int j = 1, len; j <= m && b[j] <= a[i]; ++j)
if ((len = a[i] - b[j]) < i)
chkmax(g[i], f[L[i - len] - 1] + sum(b[j], a[i]));
chkmax(f[i], g[i]);
for (int j = m, len; j && b[j] >= a[i]; --j)
if ((len = b[j] - a[i]) <= n - i)
chkmax(f[R[i + len]], g[i] + sum(a[i] + 1, b[j]));
}
std::cout << f[n] << '\n';
return 0;
}

  

[CF436D]Pudding Monsters的更多相关文章

  1. 【CF526F】Pudding Monsters cdq分治

    [CF526F]Pudding Monsters 题意:给你一个排列$p_i$,问你有对少个区间的值域段是连续的. $n\le 3\times 10^5$ 题解:bzoj3745 Norma 的弱化版 ...

  2. Codeforces 526F Pudding Monsters - CDQ分治 - 桶排序

    In this problem you will meet the simplified model of game Pudding Monsters. An important process in ...

  3. [Codeforces526F]Pudding Monsters 分治

    F. Pudding Monsters time limit per test 2 seconds memory limit per test 256 megabytes In this proble ...

  4. CodeForces526F:Pudding Monsters (分治)

    In this problem you will meet the simplified model of game Pudding Monsters. An important process in ...

  5. CF526F Pudding Monsters

    CF526F Pudding Monsters 题目大意:给出一个\(n* n\)的棋盘,其中有\(n\)个格子包含棋子. 每行每列恰有一个棋子. 求\(k*k\)的恰好包含\(k\)枚棋子的子矩形个 ...

  6. 「CF526F」 Pudding Monsters

    CF526F Pudding Monsters 传送门 模型转换:对于一个 \(n\times n\) 的棋盘,若每行每列仅有一个棋子,令 \(a_x=y\),则 \(a\) 为一个排列. 转换成排列 ...

  7. 【CF526F】Pudding Monsters

    题意: 给你一个排列pi,问你有对少个区间的值域段是连续的. n≤3e5 题解: bzoj3745

  8. Pudding Monsters CodeForces - 526F (分治, 双指针)

    大意: n*n棋盘, n个点有怪兽, 求有多少边长为k的正方形内恰好有k只怪兽, 输出k=1,...,n时的答案和. 等价于给定n排列, 对于任意一个长为$k$的区间, 若最大值最小值的差恰好为k, ...

  9. Codeforces 526F Pudding Monsters

    先把题目抽象一下: 有一个静态的数组,求有多少个区间[i,j]满足:j-i==max{ai,...,aj}-min{ai,...,aj} 也就是要求max-min+i-j==0的区间数 所以肿么做呢? ...

随机推荐

  1. 交互设计算法基础(4) - Hash Table

    import java.util.Map; // Note the HashMap's "key" is a String and "value" is an ...

  2. C语言-----野指针

    问题所在 1.局部指针变量没有被初始化 2.使用已经释放过后的指针 3.指针所指向的变量在指针之前被销毁 4.结构体成员指针未初始化, 没有为结构体指针分配足够的内存 ,内存越界(考虑使用柔性数组)和 ...

  3. sublime text 3插件改造之AutoFileName去掉.vue文件中img标签后面的width和height,完全去掉!!

    在.vue文件中img标签使用autofilename提示引入文件时,会在文件后面插入宽度高度,如下图: 文件后面会自动插入height和width,其实这两玩意儿在大多数时候并没卵用,然后就开始了百 ...

  4. Fiddler如何查找登陆的可用cookie用于其他请求?方式一

    测试过程中,如果你的请求权限是通过cookie响应而不是通过token获得,那么使用如下设置: 1.进入fiddler抓取: 2.jmeter中使用cookie 直接放进去就好了,一般浏览器cooki ...

  5. c++ 获取字符串中最长的回文子串

    #include <vector> #include <iostream> #include <string> using namespace std; strin ...

  6. eclipse为项目设置jdk

    1)在项目上右键选中properties,会进入如下界面 (2)然后点击Add Library,进入设置Library的界面 (3)选中JRE System Library进入下一界面就可以设置jdk ...

  7. es6学习3:promise

    promise含义: 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息.Pro ...

  8. how-does-mysql-replication-really-work/ what-causes-replication-lag

    https://www.cnblogs.com/kevingrace/p/6274073.html https://www.cnblogs.com/kevingrace/p/6261091.html ...

  9. 品优购商城项目(五)消息中间件 ActiveMQ

    消息中间件用于降低各个项目模块的耦合,适用于不需要等待返回消息才能进入下一个业务环节的模块,以及实时要求性不高的业务模块. 一.JMS JMS(Java Messaging Service)是Java ...

  10. 修改 commit 历史

    修改 commit 历史 参考:修改 git 历史提交 commit 信息(重写历史)git 修改已提交的内容 git init echo t.md>.gitignore git add .gi ...