Codeforces Round #700 (Div. 1) B1

B1. Painting the Array I

dp似乎不好考虑在本题 因为无论无何我们都需要维护前面的值 我只能做到n2的
我们考虑贪心:
就是把题转化成 当前数 放在那一队的后面
要是当前队尾都相等并且与x相等我们就随便放就好
因为两者性质相同 我们只考虑队尾 所以是一样的
要是队尾不相等了 我们x只有一个值
就有如下两种情况
1.与其中一个队尾不等 我们直接放过去就好了
感性理解要是我们不直接放过去 放相等的后面 我们队尾情况不变
要是后面最优再来一个相等元素我们的贡献也最多+1 和直接放是同贡献的
2.要是与其中两个队尾都不等 我们肯定要把后面越先出现的覆盖掉(这个很好理解
我们维护一个桶 二分就可以了
在这种情况就少的情况下 我们贪心也是很好考虑的 情况也不多
当然也有很多题是可以暴力dp
综上我们都需要仔细考虑性质

void solve(){
    int n;cin>>n;
    vector<int>a(n+10);
    vector<int>mp[n+10];
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mp[a[i]].push_back(i);
    }
    vector<int>b(1),c(1);
    int ans=0;
    for(int i=1;i<=n;i++){
        int x=a[i];
        if(x!=b.back()&&x!=c.back()){
            auto it=upper_bound(all(mp[b.back()]),i);
            if(it==mp[b.back()].end()){
                ans++;
                c.push_back(x);
                continue;
            }
            auto it1=upper_bound(all(mp[c.back()]),i);
            if(it1==mp[c.back()].end()){
                ans++;
                b.push_back(x);
                continue;
            }
            if(*it1<*it)c.push_back(x);
            else b.push_back(x);
            ans++;
            continue;
        }
        if(x!=b.back()){
            b.push_back(x);
            ans++;
            continue;
        }
        if(x!=c.back()){
            c.push_back(x);
            ans++;
            continue;
        }
        if(x==b.back()&&x==c.back()){
            b.push_back(x);
            continue;
        }
    }
    cout<<ans<<endl;
}
posted @ 2022-11-10 20:56  ycllz  阅读(45)  评论(0)    收藏  举报