首页 > 其他分享 >[题解]P11233 [CSP-S 2024] 染色

[题解]P11233 [CSP-S 2024] 染色

时间:2024-11-11 16:59:30浏览次数:1  
标签:P11233 题解 nullptr cin 2024 int lst tie define

P11233 [CSP-S 2024] 染色

设\(f[i][j=0/1]\)表示涂到第\(i\)位,且第\(i\)为颜色为\(j\),则考虑用\(i\)之前能和\(i\)匹配的位置\(p\)进行转移。\(p\)需要满足下面的条件:

  • \(a[p]=a[i]\)。
  • \(p\)的颜色为\(j\)。
  • \([p+1,i-1]\)之间的颜色全为\(j\)。

显然,我们只需要找满足条件的最大\(p\)即可,否则答案一定不是最优。所以我们直接维护\(lst[i]=p\)为\(i\)前面满足条件\(1\)的最大,要想满足条件\(3\),我们还需要维护\(g[l][r]\)表示\(l,r\)这个区间全部同色时,该区间的答案。然后有转移(\(p\neq 0\)时):

\[f[i][0]=\max(f[i-1][0],f[p+1][0]+a[i]+g[p+1][i-1])\\ f[i][1]=\max(f[i-1][1],f[p+1][1]+a[i]+g[p+1][i-1])\]

为什么是\(f[p+1]\)而不是\(f[p]\)?因为如果用\(f[p]\)来转移,就不能制约\([p+1,i-1]\)的颜色和\(i,p\)不同了。

然后可以注意到\(0\)和\(1\)是对称的,所以砍掉第二维是可以的。

点击查看代码
#include<bits/stdc++.h>
#define N 200010
using namespace std;
int t,n,a[N],lst[N],f[N],g[2002][2002];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>t;
	while(t--){
		memset(lst,0,sizeof lst);
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				g[i][j]=g[i][j-1]+a[j]*(a[j-1]==a[j]);
			}
		}
		for(int i=1;i<=n;i++){
			f[i]=f[i-1];
			if(lst[a[i]]) f[i]=max(f[i],f[lst[a[i]]+1]+a[i]+g[lst[a[i]]+1][i-1]);
			lst[a[i]]=i;
		}
		cout<<f[n]<<"\n";
	}
	return 0;
}

时空复杂度都是\(O(n^2)\)的,瓶颈在于预处理\(g\)。不难发现可以只保留\(g[0]\)作为\(sum\),然后用前缀和的思想,将\(g[x][y]\)转为\(sum[y]-sum[x-1]\)即可。

时空复杂度都为\(O(n)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define V 1000010
#define N 200010
using namespace std;
int t,n,a[N],lst[V],f[N],g[N];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>t;
	while(t--){
		memset(lst,0,sizeof lst);
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=2;i<=n;i++) g[i]=g[i-1]+a[i]*(a[i-1]==a[i]);
		for(int i=1;i<=n;i++){
			f[i]=f[i-1];
			if(lst[a[i]]) f[i]=max(f[i],f[lst[a[i]]+1]+a[i]+g[i-1]-g[lst[a[i]]]);
			lst[a[i]]=i;
		}
		cout<<f[n]<<"\n";
	}
	return 0;
}

标签:P11233,题解,nullptr,cin,2024,int,lst,tie,define
From: https://www.cnblogs.com/Sinktank/p/18540041

相关文章

  • [2024.11.11]NOIP模拟赛T2
    赛时T1提议看懂以后立马意识到就是让求最长Border。对于\(n\timesm\le10^6\)可以暴力建串然后直接KMP。容易发现如果\(s\)循环元为\(n\),那么答案就是\(n\times(m-1)\)。否则加上最长循环元长度即可。循环元还是用KMP求。T2让我想起了之前一道硬控我3h的题目......
  • AT_agc012_f [AGC012F] Prefix Median 题解
    首先将序列排序,这是显然的。考虑倒着确定\(b\)序列中的每个数。即从完整的\(a\)序列开始,每次删掉两个数,记录中位数。先找出\(b\)序列合法的条件。容易发现对于所有\(i\),在\(b_{p_i}\)成为中位数时,\(p_i,p_{i+1}\)之间的所有数都已经被删除了,且\(i\lep_i\le2n-i\)。......
  • NOIP2024加赛4
    NOIP2024加赛4\(T1\)luoguP11267【MX-S5-T1】王国边缘\(85pts\)预处理前缀中最后一个\(1\)出现的位置然后就可以倍增跳了。点击查看代码constllp=1000000007;intnxt[200010][62],f[200010][62],last[200010];chart[200010];lldivide(lls,llk){llan......
  • 2024双十一数码好物推荐?双十一超值数码好物汇总别错过!
    随着2024年双十一购物狂欢节临近尾声,各大电商平台的促销活动已经进入了最后的冲刺阶段。在这场年度最大的购物盛宴中,数码产品无疑是消费者关注的焦点。无论是提升工作效率的电脑、平板,还是丰富娱乐生活的手机、耳机,各大品牌纷纷推出了诱人的折扣和优惠,吸引了无数消费者的关注。......
  • Eplan2022卡顿问题解决
    EPLAN2022卡顿崩溃怎么解决 第一步:可以检查下用户设置。打开菜单"选项→设置:用户→翻译→字典":不勾选"自动完成"和"自动更正"。在选项设置框中输入"自动",快速找到用户设置,取消勾选,如下图。 第二步:可以检查下电脑语言设置。设置:常规→兼容性"。如下图。 ......
  • 代码静态测试工具Klocwork 2024.3
    HelixQAC2024.3附带适用于Windows和Linux的基于Qt的新安装程序,并增强了对ValidateSAML/OIDC身份验证的支持。此版本还包括对某些环境的Dataflow稳健性的改进,以及整个产品中的许多生活质量增强功能。  Jumpto你喜欢的部分��C++分析增强功能Validate平台改进......
  • CF 1257 题解
    CF1257题解ATwoRivalStudents每次交换都可以让距离增加\(1\),上界是\(n-1\).题目说至多而不是恰好交换\(x\)次,于是不需要考虑边界.BMagicStick一个重要的观察是:如果能够得到\(x\),那么就能得到任意小于等于\(x\)的数,这是操作二保证的.考虑操作\(1\)......
  • 【AE2024】Adobe After Effects专业视频特效制作软件下载安装(附百度云链接)
    一、AdobeAfterEffects软件简介1.什么是AdobeAfterEffectsAdobeAfterEffects,简称AE,是Adobe公司推出的专业视频特效制作软件,广泛用于影视后期制作、视频剪辑、动画制作等领域。AE在图像合成、视觉特效和动态图形制作方面表现出色,能够帮助用户创建各种复杂的视觉......
  • 2024年值得关注的8种SEO趋势
    2024年值得关注的8种SEO趋势1.核心网络生命力指标1.1基本概念1.2作用说明示例一:优化LCP示例二:减少FID示例三:降低CLS2.语义化HTML2.1基本概念2.2作用说明示例四:使用语义化标签3.无障碍性3.1基本概念3.2作用说明示例五:添加ARIA属性4.移动优先4.1基本概念4.2作用说明示例......
  • 2024年前端面试高频题(一)
    1.什么是事件冒泡和事件捕获事件流有三个阶段:事件捕获、事件目标、事件冒泡。在事件捕获阶段,事件从文档的根节点向下传播到目标元素;在事件冒泡阶段,事件从目标元素向上传播到文档的根节点。事件冒泡与事件捕获的区别事件捕获:事件从document→parent→child(从外到内)事......