[CF1479B2/CF1480D2] Painting the Array II

[CF1479B2/CF1480D2] Painting the Array II

Description

将一个序列拆成两个子序列,然后每个子序列中相邻相同的元素只保留一个,最小化剩下元素的个数。

Solution

贪心,决定每个元素 (a[i]) 放在哪里,需要考虑 (a[i]),下个和 (a[i]) 相等的数的位置,以及当前已有子序列的末尾

每个元素进来的时候,如果不能直接接在一个相同的末尾后面的话,必然要毁掉一个当前的末尾延续到下一个相同元素的可能

设 A 队队尾的下个元素位置为 pA,B 队为 pB

如果 pA 小于 pB,意味着 B 队尾在今后遭遇危险的可能性更大,因此我们选择 B 插入,反之亦然

#include <bits/stdc++.h>
using namespace std;

#define int long long 
const int N = 100005;

int n,a[N];
vector <int> g[N];
int nxt[N];

signed main()
{
    ios::sync_with_stdio(false);

    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i], g[a[i]].push_back(i);

    for(int i=1;i<=n;i++) nxt[i]=n+1;
    for(int i=1;i<=n;i++) for(int j=1;j<g[i].size();j++) nxt[g[i][j-1]]=g[i][j];

    int val1=0,nxt1=n+1,val2=0,nxt2=n+1;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int val=a[i];
        if(val==val1) nxt1=nxt[i];
        else if(val==val2) nxt2=nxt[i];
        else 
        {
            if(nxt1>nxt2) 
            {
                val1=val;
                nxt1=nxt[i];
                ++ans;
            }
            else
            {
                val2=val;
                nxt2=nxt[i];
                ++ans;
            }
        }
    }
    cout<<ans<<endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/14387533.html