Luogu P11233 CSP-S2024 染色 题解 [ 蓝 ] [ 线性 dp ] [ 前缀和优化 ]

染色:傻逼题。

赛时没切染色的都是唐氏!都是唐氏!都是唐氏!都是唐氏!都是唐氏!都是唐氏!都是唐氏!

包括我。

真的太傻逼了这题。

我今晚心血来潮一打这题,随便优化一下,就 AC 了。

怎么做到这么蠢的啊我。

暴力 dp

不要从子串的角度去考虑,我们对每一个数进行考虑 dp,否则会和我在场上一样想成用区间设计 dp,并且只能打出 \(O(n^4)\) 的暴力出来。

设计 \(dp_{i}\) 表示考虑到第 \(i\) 个数的最大值。

这里不用设计两种颜色的状态,因为他们本质上都是一样的,我们分段时只注重前一段的开头的前一个数,仅此而已。

那么很显然就可以打个 \(n^2\) 的暴力了吧?然后 \(50pts\) 到手,然后我考场上没想出来,太傻逼了。

值域优化

显然,我们不用枚举前一段的开头的前一个数在哪,只需要知道它的值是什么就好了。这样就能根据前缀取个最大值进行 dp 了。

设计 \(dp_{i,v}\) 表示考虑到第 \(i\) 个数,本段区间的开头的前一个数是 \(v\) 时的最大答案。为啥是本段呢,因为下一段转移的时候,这里的本段就成了前一段。

于是显然就维护一个线段树转移一下就好了啊。

有两种转移,第一个是同色转移,第二个是不同色转移。

同色转移

条件:\(a_i=a_{i-1}\)

我们只要给线段树上每一个点加上 \(a_i\) 即可。

异色转移

条件:无。

显然的转移:

\[dp_{i,a_{i-1}}=\max(\max_{j=1}^{j=V_{max}} dp_{i-1,j},a_i+dp_{i-1,a_i}-[a_i=a_{i-1}]\times a_i) \]

就是要么这一段开头与前一段开头的前一个数不相等,挑一个最大值转移,要么就是相等,加上贡献即可,注意由于之前进行过同色转移,要减掉这一部分的贡献。(可以证明同色转移之后一定是最大的,因为毕竟都把之前所有值的最大值加了 \(a_i\) 嘛)

时间 \(O(t n \log V)\),有几率被卡。

数组优化

观察到只有全局最大值,全局加,单点修改操作,于是直接把线段树换成数组省去一个老哥即可。

全局加直接打懒标记就好。

由于懒标记一视同仁,所以比较加懒标记之前的 dp 值转移,输出时加上懒标记即可。

时间 \(O(tV)\),单组数据时间复杂度瓶颈在于初始化。

代码

/*
定义 dp_i,0/1 表示第 i 个数染色为 1 或 0 时的最大得分。
我们分别维护每种元素在考虑到第 i 个元素时充当上一段段尾的最大得分。

和上个数同色时:
当 i=i-1 时,此时前面的数里面全部加该点的点权。
否则不做任何改动。

这个数作为新开头:
修改上一个元素在 dp 里的值。
转移是 dp_{i-1}=max(allmax,a_i+dp_{i}-[i==i-1]*a[i])
*/
#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
ll n,a[200005],dp[1000005],add,mx=0;
void solve()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    memset(dp,-0x3f,sizeof(dp));
    add=0;
    mx=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]==a[i-1])add+=a[i];
        dp[a[i-1]]=max(mx,a[i]+dp[a[i]]-(a[i]==a[i-1])*a[i]);
        mx=max(mx,dp[a[i-1]]);
    }
    cout<<mx+add<<'\n';
}
int main()
{
    //freopen("color.in","r",stdin);
    //freopen("color.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)solve();
    return 0;
}
posted @ 2024-11-22 00:55  KS_Fszha  阅读(1)  评论(0编辑  收藏  举报