Codeforces 2153D Not Alone 题解 [ 绿 ] [ 线性 DP ] [ 分类讨论 ]

news/2025/10/11 1:16:50/文章来源:https://www.cnblogs.com/zhr0102/p/19134137

Not Alone:唐题。

容易将题意转化为:环上的每一个颜色段长度都 \(\ge 2\),求最小操作数。

再考虑一个 \(O(n^2\log n)\) 的暴力,定义 \(dp_i\) 表示以 \(i\) 结尾的最小操作数,然后枚举前一个转移点 \(j\)。继续考虑如何计算 \([j + 1, i]\) 的最小操作数,容易注意到这是个经典的绝对值不等式,于是取中位数即可。

感性地发现一大段相等的数不如拆成几个小段的区间。于是从 \(n = 2, 3,4\) 的情况入手,发现:

  • \(n = 2\) 时,只能全部相等。
  • \(n = 3\) 时,只能全部相等。
  • \(n = 4\) 时,\([a_1, a_2, a_3, a_4]\) 分成 \([a_1, a_2],[a_3, a_4]\) 比直接不分段更优秀,因为分段时的代价就是 \(|a_2 - a_1| + |a_4 - a_3|\),不分段的时候,分类讨论中位数的位置发现最小值才是 \(|a_2 - a_1| + |a_4 - a_3|\),甚至有可能比它更大。因此不分段一定不优。
  • \(n = 5, 6, 7, \cdots\) 时,类似 \(n = 4\),考虑数学归纳法,发现分成若干个长度为 \(2, 3\) 的段一定最优。

于是线性 DP 求解最小方案即可。

拓展到环上,破环为链复杂度会爆炸,所以只需要分类讨论首尾相接处的情况即可。详见代码,时间复杂度 \(O(n)\)

#include <bits/stdc++.h>
#define fi first
#define se second
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
#define lc(x) (tr[x].ls)
#define rc(x) (tr[x].rs)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi = pair<int, int>;
const int N = 400005;
const ll inf = 0x3f3f3f3f3f3f3f3f;
ll n, a[N], ans, res, dp[N];
ll work(int l, int r)
{dp[l - 1] = 0;for(int i = l; i <= r; i++){dp[i] = inf;if(i == l) continue;// 2dp[i] = min(dp[i], dp[i - 2] + abs(a[i] - a[i - 1]));// 3if(i == l + 1) continue;int mx = max(a[i], max(a[i - 1], a[i - 2])), mn = min(a[i], min(a[i - 1], a[i - 2]));int md = (a[i] ^ a[i - 1] ^ a[i - 2] ^ mx ^ mn);dp[i] = min(dp[i], dp[i - 3] + mx - md + md - mn);}return dp[r];
}
void solve()
{cin >> n;ans = inf;for(int i = 1; i <= n; i++)cin >> a[i];// 0 + 0ans = min(ans, work(1, n));// 1 + 1if(n > 3)ans = min(ans, work(2, n - 1) + abs(a[1] - a[n]));// 1 + 2if(n > 4){int mx = max(a[1], max(a[n], a[n - 1])), mn = min(a[1], min(a[n - 1], a[n]));int md = (a[1] ^ a[n - 1] ^ a[n] ^ mx ^ mn);ans = min(ans, work(2, n - 2) + mx - md + md - mn);}// 2 + 1if(n > 4){int mx = max(a[1], max(a[n], a[2])), mn = min(a[1], min(a[2], a[n]));int md = (a[1] ^ a[2] ^ a[n] ^ mx ^ mn);ans = min(ans, work(3, n - 1) + mx - md + md - mn);}cout << ans << "\n";
}
int main()
{//freopen("sample.in", "r", stdin);//freopen("sample.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin >> t;while(t--) solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/934501.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

__closure__:闭包的“身份证”

要理解“闭包函数和嵌套函数的区别在于 __closure__ 属性”,首先需要明确 嵌套函数 和 闭包函数 的基础关系——闭包函数是“满足特定条件的嵌套函数”,而 __closure__ 属性正是闭包函数区别于普通嵌套函数的“标志性…

Codeforces Round 1057 (Div. 2)

A. Circle of Apple Trees 题意:一个环形数组,每次到一个位置可以选择拿走这个元素或者跳过,然后走到下一个位置。每次拿的数要比之前拿的大,求最多拿多少数。 显然可以从小到大拿,那么答案就是不同数的个数。点击…

“表达式”(Expression)和“语句”(Statement)概念辨析

在编程中,“表达式”(Expression)和“语句”(Statement)是两个基础且容易混淆的概念。它们的核心区别在于是否有返回值以及在代码中的作用,以下从定义、特点、示例三个维度详细说明: 一、定义与核心区别表达式(…

每日一题 ###121买卖股票的最佳时机

仅以此记录所学所想,如有错误,还望指正。 首次尝试 1、我小小的脑子只能想出暴力解法,结果是超时了。 class Solution { public:int maxProfit(vector<int>& prices) {int max=0;for(int i=0;i<prices…

10.10总结

1.将一个数组中的值按逆序重新存放进行了编程联系,生成了对应程序 2.明天学习完善程序细节 3.今天收获满满

LibreChat-图文并茂手把手教你界面配置 | Adorable LibreChat Interface Configuration Guide

@目录🎀 整体介绍 | Overview🍪 配置项详解 | Field Details🎨 开关大全 | All Switches✨ 配置示例 | Cute ExampleConclusion | 结语 🎀 整体介绍 | Overview 今天我们来学习一下,LibreChat的页面基础配置哇…

GAE-广义优势估计算法介绍

一句话总结 GAE 就像「既要稳又要准」的聪明妥协:用多步 TD 误差加权平均,既缓解了 MC 的高方差,又减少了 TD 的单一偏差,通过调节参数(λ)灵活平衡两者的优缺点。MC vs TD 的痛点MC(蒙特卡洛):原理:跑完整个…

qemu模拟单片机

ESP32 乐鑫官方移植的qemu工程:espressif/qemu: Fork of QEMU with Espressif patches. See Wiki for details. 官方使用说明:esp-toolchain-docs/qemu/README.md at main espressif/esp-toolchain-docs 目前支持ES…

RAG-检索增强生成

检索增强生成(Retrieval-Augmented Generation, RAG)是近年来深度学习领域的重要技术突破,旨在解决大语言模型(LLM)在知识更新、事实准确性以及领域专业化方面的局限性。本文将从核心架构、功能实现、实践规范到高…

“猴子补丁”(monkey patch)跟猴子有关吗?

“猴子补丁”(monkey patch)指的是使函数名指向另一个函数。 这个名字里的“猴子”(monkey)和真实的动物猴子没有任何生物学或实体关联,它是编程领域的一个形象比喻,名字的由来与“猴子”的俚语含义有关。 为什么…

Yapi 使用docker在cenos7上部署教程与基本使用

✅ 前提条件 确保你已经完成以下准备:CentOS 7 系统已安装 Docker(未安装请先安装)拥有管理员权限(root 或 sudo)1、安装mongo数据库# 拉取mongo镜像,有本地镜像包可以直接导入 docker pull mongo # 安装mongo数…

C语言vsC++

一、核心区别设计理念C 语言:面向过程(Procedure-Oriented),以函数和数据结构为核心,强调算法和步骤的实现,关注 “怎么做”。 C++:基于 C 语言扩展而来,支持面向对象编程(Object-Oriented,OO),引入类、对…

20251010 之所思 - 人生如梦

20251010 之所思这两天想的事情有点多,有点焦虑,因为刚刚升职,部门的软件需要管理起来,已经不再仅仅管理自己现在的一个小组,今天看了一下软件的人数,数量已经到了122人,这是一个很庞大的队伍,如何管理好,心里…

2025.10.10

今天学生会开会导致十点没有回到宿舍 今天一节英语课,单词背诵情况不好,以后会加强 尝试轻食餐,不好吃

个人书单-从心流出发,学习积极心理学

从“心流”出发,构建你的积极心理学知识体系 | 专题书单 你是否曾有过这样的体验:在全神贯注地工作、运动或创作时,忘记了时间的流逝,内心充满了一种纯净而高效的愉悦感? 这就是米哈里契克森米哈赖所描述的 “心流…

等号(=)在C语言和python中有什么区别?

等号(=)在C语言和python中有什么区别? 等号(=)在 C 语言和 Python 中虽然核心功能都是“赋值”,但由于两种语言的设计理念(静态类型 vs 动态类型、编译型 vs 解释型)存在根本差异,= 的行为、特性和使用场景有…

AI元人文(十四)之价值共生篇:再论物物交换——作为价值共生基础的元协议

AI元人文(十四)之价值共生篇:再论物物交换——作为价值共生基础的元协议 文 / 岐金兰 摘要: 本文是对前文《AI元人文(十四):物物交换——论跨领域价值协商的元协议》提出的“物物交换”元协议的深化探讨。文章将…

4.布局系统

Aquarius 开发框架旨在帮助独立开发者和中小型团队,完成 iOS App 的快速实现与迭代。使用框架开发将给你带来简单、高效、易维护的编程体验。大家好,我是K哥。一名独立开发者,同时也是Swift开发框架【Aquarius】的作…

虚拟环境QA

Dingxingdi: 我使用conda激活虚拟环境之后,就可以像往常一样使用命令了吗?不需要在命令前面加一个conda吗? GitHub Copilot: 可以直接像平常一样运行命令,不需要在命令前加 conda。激活环境(例如 conda activate …

提升高度的网站

真相查询类Snopes https://www.snopes.comWikipedia(英文) https://en.wikipedia.org全球时事类 3. Foreign Affairs https://www.foreignaffairs.comBrookings https://www.brookings.edu课程学习类 5. Open Yale C…