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;
}

浙公网安备 33010602011771号