当前位置: 首页 > news >正文

P11233 [CSP-S 2024] 染色

P11233 [CSP-S 2024] 染色

难度:提高+/省选-

考点:DP

题意

  • 给定 n n n 个数 A i A_i Ai,对 A i A_i Ai 进行染色,只有两种颜色。设 C C C A A A 染色后的数组。

    • 如果 A i A_i Ai 左侧没有预期同色的数,则令 C i = 0 C_i = 0 Ci=0。否则,记其左侧与其最靠的同色数为 A j A_j Aj,若 A i = A j A_i=A_j Ai=Aj,则令 C i = A i C_i=A_i Ci=Ai,否则令 C i = 0 C_i = 0 Ci=0
  • 题目求: ∑ i = 1 n C i \sum_{i=1}^{n} C_i i=1nCi,需要最大化最终得分,请求出最终得分的最大值

分析

20 p t s 20pts 20pts

​ 数据范围: n ≤ 15 n \le 15 n15,暴力枚举每个数字两种染色的情况 2 n 2^n 2n,然后扫描一遍 O ( n ) O(n) O(n),找出最大分值,时间复杂度: O ( T × n × 2 n ) ≈ 9.8 × 1 0 6 ≤ 1 0 8 O(T \times n \times 2^n)≈ 9.8 \times 10^6 \le 10^8 O(T×n×2n)9.8×106108 是可以接受的。

50 p t s 50 pts 50pts

想拿满分,最优性问题要 D P DP DP 解法了。


二维 DP 作为思路启发:

设: f ( i , j ) f(i,j) f(i,j) i i i 个数,第 j j j 个数染色为 j j j 的最大分值。

分类讨论:

  • 1 ∼ a i − 1 1 \sim a_{i-1} 1ai1 都没有相同的数,则贡献 f ( i , 0 ) = f ( i , 1 ) = m a x ( f ( i − 1 , 0 ) , f ( i − 1 , 1 ) ) f(i,0) = f(i,1) = max( f(i-1,0),f(i-1,1) ) f(i,0)=f(i,1)=max(f(i1,0),f(i1,1))

  • 1 ∼ a i − 1 1 \sim a_{i-1} 1ai1 前面存在相同的数,假设以染色为 0 0 0 来看 f ( i , 0 ) f(i,0) f(i,0),前面确定也存在一个染色染色为 0 0 0 的数 ( a i = a j ) (a_i = a_j) (ai=aj)

    这之间所有的数都染色为 1 1 1。确定是前面最靠近相同的数染为相同色,否则在这之间找到相同的数并染色为同色收益也会更大。相同色的数的位置(可预处理出来, O ( n ) O(n) O(n)),则要分 3 3 3 部分进行计算贡献:

    l [ i ] l[i] l[i]:表示数字 i i i 左侧最靠近且相同的数字位置下标。

在这里插入图片描述
部分 ①

​ 位置 ( 1 , l [ a i ] + 1 ) (1,l[a_i]+1) (1,l[ai]+1) 数产生的贡献,其中 l [ a [ i ] ] + 1 l[a[i]] + 1 l[a[i]]+1 染成 1 1 1,即 f ( l [ a i ] + 1 , 1 ) f(l[a_i]+1,1) f(l[ai]+1,1) 的贡献。不用担心(没有被染成 0 0 0)的问题,因为 f ( l [ a i ] , 1 ) f( l[a_i],1 ) f(l[ai],1) 会选择最优的策略,那么(此时可以选择不和 l [ a i ] + 1 l[a_i]+1 l[ai]+1)染为同色。

部分 ②

​ 位置 $ l[a_i]+2 \sim i-1 $ 的数产生的贡献,这贡献会把区间 l + 1 ∼ i − 1 l+1 \sim i-1 l+1i1 染为同色产生的贡献计算上,设 s i s_i si 1 ∼ i 1 \sim i 1i 位置上染为同色的贡献。那么 l + 1 ∼ i − 1 l+1 \sim i-1 l+1i1 全部染为同色所产生的的贡献,或可以表示为 l + 2 ∼ i − 1 l+2 \sim i-1 l+2i1 数产生的贡献 ( s i − 1 ∼ s l + 1 ) (s_{i-1} \sim s_{l+1}) (si1sl+1)

部分 ③

​ 在 i i i 位置上的数,贡献就是 a i a_i ai

上述对应的 3 个部分,可以表示如下图所示:

在这里插入图片描述
对于前面存在相同数字的贡献,总结:
f ( i , 0 ) = { f ( l i + 1 , 1 ) ( s i − 1 − s l i + 1 ) a i f(i,0) = \left\{ \begin{array}{lc} f( l_{i+1},1 )\\ (s_{i-1} - s_{l_i+1})\\ a_i \end{array} \right. f(i,0)= f(li+1,1)(si1sli+1)ai
特判 a i = a i − 1 a_i = a_{i-1} ai=ai1 的情况,即 f ( i , 0 ) = f ( i − 1 , 0 ) + a i f(i,0) = f(i-1,0)+a_i f(i,0)=f(i1,0)+ai f ( i , 1 ) = f ( i − 1 , 1 ) + a i f(i,1) = f(i-1,1) + a_i f(i,1)=f(i1,1)+ai

在产生贡献和不产生贡献中最大分值中取 m a x max max:
{ f ( i , 0 ) = m a x ( f ( i − 1 , 0 ) , f ( i − 1 , 1 ) , a i + f ( l i + 1 , 1 ) + ( s i − 1 − s l i + 1 ) ) f ( i , 1 ) = m a x ( f ( i − 1 , 0 ) , f ( i − 1 , 1 ) , a i + f ( l i + 1 , 0 ) + ( s i − 1 − s l i + 1 ) ) a n s = m a x ( f ( n , 0 ) , f ( n , 1 ) ) \left\{ \begin{array}{lc} f(i,0) = max( f(i-1,0), f(i-1,1), a_i + f(l_{i}+1,1) + (s_{i-1} - s_{l_{i}}+1) )\\ f(i,1) = max( f(i-1,0), f(i-1,1), a_i + f(l_{i}+1,0) + (s_{i-1} - s_{l_{i}}+1) )\\ \end{array} \right. \newline ans = max( f(n,0), f(n,1) ) {f(i,0)=max(f(i1,0),f(i1,1),ai+f(li+1,1)+(si1sli+1))f(i,1)=max(f(i1,0),f(i1,1),ai+f(li+1,0)+(si1sli+1))ans=max(f(n,0),f(n,1))

最开始就是如上的思路去解题的,但想了一下第二个维度有必要开么?

感觉可以去掉,再思考一下。


返璞归真,简单的状态表示:

​ 设状态 f i f_i fi 表示前 i i i 位数的最大分值和。显然对于每一个位置 i i i 可以令 f i = f i − 1 f_i=f_{i-1} fi=fi1

​ 用 l i l_i li 记录 i i i 上一次出现的位置,初始化令所有的 l i = 0 l_i = 0 li=0,每遍历到一个位置,动态更新 l a i = i l_{a_i} = i lai=i。然后枚举区间更新 f i f_i fi,也可以预处理 g g g 数组 g [ i ] [ j ] g[i][j] g[i][j] 表示区间 [ i , j ] [i,j] [i,j] 的染色为相同时的最大分值之和,复杂度是 O ( n 2 ) O(n^2) O(n2) n ≤ 1 0 3 n \le 10^3 n103 50 p t s 50pts 50pts 到手。

参考代码

// 50pts
#include <bits/stdc++.h>
const int N = 2e3 + 5;int n, T;
int a[N], lst[N];  // lst[i]:表示数字 i 最靠近 i 左侧的数字位置
int f[N], g[N][N]; // f[i] ::: 表示考虑前 i 个数贡献的最大分值之和int main()
{std::cin >> T;while (T--){memset(a, 0, sizeof a), memset(lst, 0, sizeof lst), memset(f, 0, sizeof f), memset(g, 0, sizeof g);std::cin >> n;for (int i = 1; i <= n; i++)std::cin >> a[i];for (int i = 1; i <= n; i++) // 构造 区间 [i,j] 染色相同的最大分值之和for (int j = i + 1; j <= n; j++){g[i][j] = g[i][j - 1];if (a[j] == a[j - 1])g[i][j] += a[j];}for (int i = 1; i <= n; i++){if (lst[a[i]] == 0) // 前 i-1 位不存在相同的数字 a[i]{lst[a[i]] = i;   // 更新数字 a[i] 最后一次出现的下标f[i] = f[i - 1]; // 继承前 i-1 位的最大分值}else{f[i] = std::max(f[i - 1], std::max(f[lst[a[i]] + 1], f[lst[a[i]]]) + a[i] + g[lst[a[i]] + 1][i - 1]);lst[a[i]] = i; // 更新数字 a[i] 最后一次出现的下标}}std::cout << f[n] << "\n";}return 0;
}

100 p t s 100pts 100pts

n ≤ 1 0 6 n\le 10^6 n106 g [ i ] [ j ] g[i][j] g[i][j] 开不下这么大的数组。用前缀和优化,每当 a i = a i − 1 a_i = a_{i-1} ai=ai1 时候,更新前缀和数组 s i s_i si。最后对于 a i a_i ai 如果 l a i l_{a_i} lai 存在,则对 f i f_i fi 转移:
f i = ( 1 ≤ i ≤ n ) m a x { f l a i + 1 , a i , ( s i − s l a i ) } f_i = (1 \le i \le n ) \space max\{ f_{l_{a_i}+1}, a_i,( s_i-s_{l_{a_i}}) \} fi=(1in) max{flai+1,ai,(sislai)}
参考代码

#include <bits/stdc++.h>
#define ll long longconst int N = 1e6 + 10;
// f[i] ::: 表示前 i 个数,最大分值之和, lst[i] ::: 表示数字 i 前面最靠近的相同数字位置, s[i] ::: 表示前 i 个数染相同颜色的总贡献
ll f[N], s[N], lst[N], a[N];
ll n, T;int main()
{std::ios::sync_with_stdio(false), std::cin.tie(nullptr);std::cin >> T;while (T--){memset(f, 0, sizeof f), memset(s, 0, sizeof s), memset(lst, 0, sizeof lst), memset(a, 0, sizeof a);std::cin >> n;for (int i = 1; i <= n; i++)std::cin >> a[i];// 构造 1~i 个数,全部数字染色相同时的最大分值之和for (int i = 2; i <= n; i++)s[i] = (a[i] == a[i - 1] ? s[i - 1] + a[i] : s[i - 1]);for (int i = 1; i <= n; i++) // 枚举数字的位置 i{f[i] = f[i - 1]; // 省去判断,默认继承if (lst[a[i]])   // 如果前面存在相同的数字, 则将 3 部分的贡献作对比更新f[i] = std::max(f[i], f[lst[a[i]] + 1] + a[i] + s[i] - s[lst[a[i]] + 1]);lst[a[i]] = i; // 更新数字 a[i] 出现的位置}std::cout << f[n] << "\n";}return 0;
}

相关文章:

P11233 [CSP-S 2024] 染色

P11233 [CSP-S 2024] 染色 难度&#xff1a;提高/省选-。 考点&#xff1a;DP。 题意&#xff1a; 给定 n n n 个数 A i A_i Ai​&#xff0c;对 A i A_i Ai​ 进行染色&#xff0c;只有两种颜色。设 C C C 为 A A A 染色后的数组。 如果 A i A_i Ai​ 左侧没有预期同…...

图传推流学习(敬请期待)

图传推流简介 1.RTSP、RTP与RTCP2.搭建rtsp服务器&#xff08;资源下载&#xff09;3.搭建rtsp服务器&#xff08;搭建过程&#xff09; 1.RTSP、RTP与RTCP RTSP&#xff08;Real Time Streaming Protocol&#xff09;、RTP&#xff08;Real-time Transport Protocol&#xff0…...

【JavaGuide】十大经典排序算法总结

冒泡排序 算法步骤 不断的两两比较&#xff0c;这样当前最大的元素总是会排在最后面。所以称为冒泡。 图解算法 代码实现 public static int[] bubbleSort(int[] arr) {// i是排好了几个数for (int i 1; i < arr.length; i) {// flag标记当前循环是否调整了顺序&#xff0c…...

程序中怎样用最简单方法实现写excel文档

很多开发语言都能找到excel文档读写的库&#xff0c;但是在资源极其受限的环境下开发&#xff0c;引入这些库会带来兼容性问题。因为一个小功能引入一堆库&#xff0c;我始终觉得划不来。看到有项目引用的jar包有一百多个&#xff0c;看着头麻&#xff0c;根本搞不清谁依赖谁。…...

《机器学习与人类学习:比较、融合与未来展望》

《机器学习与人类学习&#xff1a;比较、融合与未来展望》 一、引言二、机器学习的概念与发展&#xff08;一&#xff09;机器学习的定义与分类&#xff08;二&#xff09;机器学习的发展历程&#xff08;三&#xff09;机器学习的应用领域 三、人类学习的本质与过程&#xff0…...

Mysql 8.4.3LTS 的离线部署

文章目录 一、部署环境资源配置 二、下载地址版本选择 三、部署详情1. 上传安装包2. 解压软件包3. 安装mysql3.3.1 创建mysql用户与用户组3.3.2 授权安装文件夹3.3.3 安装libaio依赖 &#xff08;坑&#xff09;ubuntu24.04 中关于libaio的坑 3.3.4 初始化Mysql数据库3.3.5 编辑…...

h5项目打包上线报错404文件找不到

配置一下路由就可以了 1.找到项目里的这个文件 2.滑到最下面‘源码视图’ 3.找到base&#xff0c;没有的话写上一个&#xff0c;保存后打包就可以了 "h5" : {"router" : {"base" : "./"}}...

mysql上课总结(5)(MySQL的完整性约束(详细介绍))

目录 一、完整性约束。 &#xff08;1&#xff09;概念与目的。 <1>概念。 <2>目的。 &#xff08;2&#xff09;各个约束的详细&#xff08;表格&#xff09; &#xff08;3&#xff09;各个约束的简要总结。 <1>主键约束。 <2>唯一约束。 <3>非…...

复原IP地址

分割字符串的姐妹题 题目&#xff1a;93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; 题解&#xff1a;代码随想录 代码&#xff1a; class Solution {List<String> resnew ArrayList<>();public List<String> restoreIpAddresses(String s) …...

Effective C++ 学习笔记二

Effective C 学习笔记二 文章目录 Effective C 学习笔记二别让异常逃离析构函数绝不在构造和析构的过程中调用virtual函数令operator 返回一个reference to *this在operator中处理"自我赋值"C四种转换 别让异常逃离析构函数 C 并不禁止析构函数吐出异常&#xff0c;…...

以「JIMUMETA元宇宙体验馆」为例,探讨有哪些元宇宙场景?

让我们以「JIMUMETA元宇宙体验馆」为例&#xff0c;深入探讨元宇宙场景中提供的产品与服务。该体验馆由视创云展精心打造&#xff0c;集成了企业主展馆、元宇宙虚拟活动分会场、品牌展示分会场、线上论坛会场以及会议室接待会客等多重功能&#xff0c;旨在全方位满足企业发布会…...

RHCE的练习(8)

动态网站 lnmp&#xff08;LAMP&#xff09; 解析index.php界面 &#xff08;1&#xff09;预配&#xff0c;确保服务能够被访问 systemctl stop firewalld setenforce 0 &#xff08;2&#xff09;安装nginx服务 mount /dev/sr0 /mnt cat /etc/yum.repos.d/base.repo dnf …...

yocto是如何收集recipes,如何加入现有的bb文件

yocto通常是如何收集recipes: 在Yocto中&#xff0c;通过以下方式收集recipes&#xff1a; 层&#xff08;Layers&#xff09; Yocto项目使用层来组织recipes。层是包含配置文件、recipes和其他相关文件的目录结构。每个层有自己的目录&#xff0c;其中 recipes-* 目录用于存…...

[运维] 服务器本地网络可用性检查脚本

引言 在日常活动中&#xff0c;我遇到过一个令人头疼的问题。测试使用的远程终端在第二天继续使用时可能就发生无法与外网通信的情况&#xff0c;往往连上终端后在拉取资源时才能发现。这导致每次使用前都需要手动检查网络状况&#xff0c;增加了不必要的麻烦。为了简化这一过…...

MYSQL-显示信息关于服务器插件语法(二十五)

13.7.5.25 SHOW PLUGINS 语句 SHOW PLUGINSSHOW PLUGINS 显示信息 关于服务器插件。 SHOW PLUGINS 输出示例&#xff1a; mysql> SHOW PLUGINS\G *************************** 1. row ***************************Name: binlogStatus: ACTIVEType: STORAGE ENGINE Librar…...

【线下培训】龙信受邀参加开封市公安局举办的电子数据取证培训班

文章关键词&#xff1a;电子数据取证、手机取证、云取证、国产化取证 为了提升开封市公安机关在互联网电子数据取证分析方面的专业能力&#xff0c;龙信为开封市公安机关量身打造了一场高质量的电子数据取证分析技能培训课程。 本次培训课程不仅涵盖了电子数据取证的基础理论、…...

软件测试工程师面试整理 —— 编程与自动化!

在软件测试领域&#xff0c;编程与自动化是提升测试效率、覆盖率和可靠性的关键因素。掌握编程技术和自动化测试框架&#xff0c;能够帮助测试人员有效地执行大量重复性测试任务&#xff0c;并迅速反馈软件的质量状况。以下是编程与自动化在测试中的主要应用及相关技术介绍&…...

【鸿蒙新闻】10月29日警用鸿蒙开发者大会在北京胜利召开,开启智慧应用新时代!

10月29日&#xff0c;在公安部科技信息化局、公安部装备财务局指导下&#xff0c;由公安部第一研究所主办&#xff0c;鼎桥通信技术有限公司、OpenHarmony生态委员会及公共安全专委会协办的警用鸿蒙开发者大会在北京胜利召开。会议以“拥抱警鸿创新生态 开启智慧应用新时代”为…...

java.io.IOException: Too many open files

java.io.IOException: Too many open files 前言&#xff1a; 项目最近报 java.io.IOException: Too many open files 问题&#xff0c;大概意思是&#xff1a;意味着你的应用程序尝试打开的文件描述符数量超过了系统允许的最大数量&#xff0c;在linux中每个进程打开的文件描…...

ElementUI el-form表单多层数组的校验

问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; ElementUI el-form表单多层数组的校验 页面效果&#xff1a; 数据结构&#xff1a; addform: {code: ,type: ,value: ,state: 1,remark: ,fieldList: [{fieldCode: ,resolverEntities: [{resolverType: , re…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

WPF八大法则:告别模态窗口卡顿

⚙️ 核心问题&#xff1a;阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程&#xff0c;导致后续逻辑无法执行&#xff1a; var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题&#xff1a…...