CF1861D Sorting By Multiplication 题解
题意:
给定一个数组 $ A $ $ ( $ $ A_i ≥ 1 $ $ ) $ ,给定一种操作,选择一个区间 $ [l, r] $ ,选择任意一个数 $ x $ ,使得 $ A_i = A_i * x \space (l \le x \le r) $ ,要求使 $ A $ 严格递增,求最小操作次数。
思路:
考虑到 $ A_i \ge 1 $ ,$ x $ 可以为负数,那么最终严格递增的 $ A $ 分为三种情况:全是正数,全是负数,先负后正。
1. 全是正数: 只需要找到初始 $ A $ 中每个满足 $ Ai \ge Ai+1 $ 的索引 $ i $ ,选择区间 $ [i + 1, n] $ , 使得 $ A_j = A_j * INF \space (i + 1 \le j \le n)$ 即可。
2. 全是负数: 选择区间 $ [1, n] $ ,使得 $ A_i = -INF * A_i \space (1 \le i \le n)$ ,只需要找到现在 $ A $ 中每个满足 $ Ai \ge Ai+1 $ 的索引 $ i $ ,选择区间 $ [1, i] $ , 使得 $ A_j = A_j * INF \space (1 \le j \le i)$ 即可。
3. 先负后正: $ for \space i : 1 $ -> $ n $ 枚举每个负数右边界 $ i $ ,选择区间 $ [1, i] $ ,使得 $ A_j = -INF * A_j \space (1 \le j \le i) $ 。对于 $ A $ 的正数后缀 $ [i + 1, n] $ ,参考情况 $ 1 $ ;对于 $ A $ 的负数前缀 $ [1, i] $ ,参考情况 $ 2 $ 。
情况 $ 2 $ 和情况 $ 3 $ 中,选择一个区间使其变为负数,再维护该区间为严格递增,实际上等价于: 选择一个区间,维护该区间为严格递减,再将该区间变为负数。 两者操作次数相同,每次操作所选区间也相同。
情况 $ 1 $ ,等价于情况 $ 3 $ 中负数右边界为 $ 0 $;情况 $ 2 $ ,等价于情况 $ 3 $ 中负数右边界为 $ n $。
考虑正负交替的情况:由于严格递增的 $ A $ 只有 $ 3 $ 种情况,显然正负交替的情况需要变成上述 $ 3 $ 种情况之一。无论变为哪种情况,实际上等价于:情况 $ 3 $ 中,选择一个负数右边界 $ i \space (0 \le i \le n) $ ,然后将所选负数前缀中的正数变为负数,将所选正数后缀中的负数变为正数,之后参考情况 $ 1 $ 和情况 $ 2 $ 。 由于 $ A_i \ge 1 $ ,正数变为负数需要多进行至少 $ 1 $ 次操作,正数变为负数再变为正数需要多进行至少 $ 2 $ 次操作,所以一定不会优于上述 $ 3 $ 种情况。
因此,实际上只需要考虑一种情况——先负后正,负数右边界从0到n。
做法:
预处理:$ for \space i : 1 $ -> $ n $ 遍历维护 $ Less[i] $ ,表示区间$ [1, i] $ 中,$ A_i \le A_{i+1} $ 的数量。
预处理:$ for \space i : 1 $ -> $ n $ 遍历维护 $ Greater[i] $ ,表示区间 $ [1, i] $ 中, $ A_i \ge A_{i+1} $ 的数量。
最后,先考虑负数右边界为 $ 0 $ , 即全是正数的情况,令 $ ans $ $ = $ $ Greater[n] $ 。然后 $ for \space i : 1 $ -> $ n $ 遍历每个负数右边界 $ i $ , $ ans $ $ = $ $ min $ $ (ans $ ,( $ Less[i] $ $ + 1 $ ) $ + (Greater[n] - Greater[i])) $ ,即可得到最终答案 $ ans $ 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】