AGC007F 题解

题意

给定两个长为 \(n\) 的字符串 \(S, T\),求最少进行多少次操作才能使 \(S = T\)。

一次操作定义为:对于 \(i = 1, 2, .. n\),令第 \(i\) 位为操作 的第 \(i - 1\) 位或操作 的第 \(i\) 位。(\(i = 1\) 时只能第二种)

分析

赛时想了一个假的贪心,想到设 \(pos_i\) 为在答案中 \(T_i\) 是由 \(S_{pos_i}\) 贡献的,可以发现 \(\forall 1\le i < n, pos_i\le pos_{i + 1}\),而且若 \(i < j\) 有交,一定先操作完 \(j\)。

这个思路看上去没有问题,但是后面的结论是错的,当时我这样想的原因是:若 \(i\) 先操作完,\(j\) 就没有了,但真的是这样吗,可以 \(pos_i\) 先操作到 \(pos_j - 1\),\(pos_j\) 操作到 \(i + 1\) 及之后。

错误原因:并没有做到最优,能早点完成的操作放在了后面做。

Update:破案了,这道题明显是倒着做消除后效性,直接贪这么后效怎么做。倒着做好写多了/kel

考虑已经得到了 \(pos_i\)(对于 \(i\) 找第一个 \(j\) 使得 \(s_j = t_i\) 且 \(j \le pos_{i + 1}\)),相当于 \(S = 1, 2, ... n\),\(T = pos_1, pos_2, ..., pos_n\),每次我们尽量往右扩展,然后给有用的留 1 个让它往右扩展,发现这样一定是最优的。

考虑怎么维护这个,先把无用的去掉,把相同的 S 缩到一起,每次从右往左,依次进行 把当前区间缩到只有右端点,把右端点尽量向右扩展 的流程,这是好维护的。

考虑为什么对

  1. 可以根据贪心过程逆推操作
  2. 已经是最贪的了

考虑怎么维护,找规律,发现进行了 \(j\) 次操作后,当前区间 \(i\) 的 \(R_i = R_{i + j} - j\)。令 \(R_j(j > n) = +\inf\) 即可。

相关推荐
UestcXiye13 天前
Leetcode3256. 放三个车的价值之和最大 I
c++·leetcode·贪心·数据结构与算法
DieSnowK1 个月前
[Algorithm][贪心][跳跃游戏][加油站][单调递增的数字][坏了的计算器]详细讲解
贪心·单调递增的数字·新手向·跳跃游戏·algorithm·加油站·坏了的计算器
闻缺陷则喜何志丹1 个月前
【C++贪心】2498. 青蛙过河 II
c++·算法·leetcode·贪心·最小·最大·青蛙
逝去的秋风1 个月前
【代码随想录训练营第42期 Day26打卡 贪心Part1 - LeetCode 455.分发饼干 376. 摆动序列 53. 最大子序和
leetcode·贪心
Aurora_th1 个月前
贪心算法的初涉(双指针 + “过山车思想”)
算法·leetcode·codeforces·贪心·双指针·“过山车”思想
rgw20102 个月前
P6764 [APIO2020] 粉刷墙壁
动态规划·贪心·特殊性质·最小区间覆盖·apio
Aurora_th2 个月前
LeetCode 2844.生成特殊数字的最少操作(哈希表 + 贪心)
数据结构·c++·数学·leetcode·贪心·哈希表
UestcXiye2 个月前
Leetcode3219. 切蛋糕的最小总开销 II
c++·leetcode·贪心·排序·数据结构与算法
希忘auto2 个月前
贪心系列专题篇二
算法·贪心