P11233 [CSP-S 2024] 染色

[P11233 [CSP-S 2024] 染色]

说句闲话:考场没想到应该从last+1转移,怒调1.5h后20pts遗憾离场

我们记fi为考虑到第i位时的答案,sumi为[1,i]这个区间内在全染同种颜色时的贡献,lasti表示从i往左数,除本身之外第一个满足alast=ai的位置
形式化的sum: sumx=i=2x[ai=ai1]a[i]

然后我们对于每个点i:f[i]=f[i-1];如果他有last:

f[i]=max(f[i],f[last+1]+s[i]-s[last+1]+a[i]);

我们考虑如何解释这个方程:
根据last的定义:

{a[i]a[j]|j[last+1,i1]a[i]=a[last]=>collast=coli=0;collast+1=col[last+1,i1]=1

我们假设:

所以a[last]a[last+1]

如果我们从last转移到i的话,lastlasti+1对于last_i+1的贡献就会被忽略,这样我们就不能使得答案最大化了

对于有last的i:

f[last+1]保证是在col[last]col[last+1] 的时候取到的,所以我们在由last+1转移到i的时候能保证col[last]col[i],二者结合:

{col[last]col[last+1]col[last]col[i]=>col[i]=col[last]

这样就保证了从f[last+1]转移到f[i]是合法的
然后这题就并不愉快的补完了

Code:

#include<bits/stdc++.h>
#define int long long
const int N=1e6+5;
using namespace std;
int a[N],last[N],f[N];
int n,inf;
int sum[N];
inline void upd(int &x,int y)
{
x = (x>y ? x : y);
}
void work()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
last[a[i]]=0;f[i]=0;
sum[i]=sum[i-1];
sum[i]+= (a[i]==a[i-1] ? a[i] : 0);
}
for(int i=1;i<=n;i++)
{
f[i]=f[i-1];
if(last[a[i]])
{
int j=last[a[i]]+1;
upd(f[i],f[j]+a[i]+sum[i]-sum[j]);
}
last[a[i]]=i;
}
printf("%lld\n",f[n]);
}
#undef int
int main()
{
int T;
cin>>T;
while(T--)
{
work();
}
return 0;
}
posted @   liuboom  阅读(47)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验
点击右上角即可分享
微信分享提示