[CSP-S 2024] 染色

前言#

很难蚌的一次考试, 很难确定是实力问题还是什么

算法#

事实上是可以看出是 dp 题的
fi,j 为考虑到 i 位的答案, 当前颜色为 j, j0,1
lasti 表示 i 位前第一个与 i 位颜色相同的

50pts#

当前位置产生贡献#

对于 fi,j , 显然从 lasti+1i1 , 有: 颜色为 ~j
对于 50pts 的做法, 这里是可以预处理出每一个区间取一个值产生的贡献, 具体的

for (int i = 1; i <= n; i++) 
{
	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];
	}
} 

O(n2)

fi,j=flasti,j+ai+glasti+1,i1

当前位置不产生贡献#

显然有

fi,j=fi1,j

50pts 代码#

#include <bits/stdc++.h>

#define rint register int

using namespace std;

const int N = 2e3 + 5;

int n, T;
int a[N], lst[N];
int f[N], g[N][N], ans; 

signed main() 
{
	cin >> T;
	while (T--) 
	{
		cin >> n;
		memset(a, 0, sizeof a);
		memset(lst, 0, sizeof lst);
		memset(f, 0, sizeof f);
		memset(g, 0, sizeof g);
		for (rint i = 1; i <= n; i++) cin >> a[i];
		for (rint i = 1; i <= n; i++) 
		{
			for (rint 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 (rint i = 1; i <= n; i++) 
		{
			if (lst[a[i]] == 0) 
			{
				lst[a[i]] = i;
				f[i] = f[i - 1];
			} else 
			{
				f[i] = max(f[i - 1], max(f[lst[a[i]] + 1], f[lst[a[i]]]) + a[i] + g[lst[a[i]] + 1][i - 1] );
				lst[a[i]] = i;
			}
		}
		cout << f[n] << endl;
	}
	return 0;
}

正解#

考虑优化
观察到 g 数组是完全没有必要的
hi=g1,i
前缀和处理即可

正解代码#

略, 显然非常好实现

总结#

对于 dp 优化, 考虑建立辅助数组, 再想办法从辅助数组的特殊性质下手进行优化
这是一种常见的套路

posted @   Yorg  阅读(25)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示