CodeForces 1296 E2.Stringのぬりえ(ハードバージョン)

質問の意味:

長さの文字列のn与えられた
着色完了した後に、着色の文字列を与えることになりました各文字を:
文字が同じ色の隣接する位置でない場合は、自分の位置を交換することができ
、今あなたが着色のようなものを構築したいですプログラム、辞書順最小を交換することにより、最後の文字列を作成することを可能にする、異なる色の必要な最小数を着色

アイデア:

非厳密(非減少)増加している辞書最小配列
のみ位置が同じ色を交換することができるされていないため、着色が完了した後に見つけることができるが、文字の相対位置が隣人を変更しない同じ色です。
非厳密にする必要性が高まっているため、それは厳密に非増分同じ色でなければなりません。
最初の文字a1のために、左から右にトラバーサル文字列は、色があります。第2の文字A2のためにA2がA1より小さい場合、より大きいまたは等しいA2 A1場合、また、非必須が厳密に増加同じ色1であり、2着色、A1、A2と同じ色ではありません。第三文字A3は、A3最大値は、その後、着色は、前の計算または大文字A3よりも色の最大値、2である場合、MAを想定し、少なくとも着色a3はMA + 1であり、A3色(MAあります+1)と(同じ文字色とa3)の最大値。
他には、あなたが簡単に見つけることが、文字の各色の最大値を維持するために、サイズ26の配列を開くことができます。

コード:

#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
char s[maxm];
int ans[maxm];
int d[33];//每种字符的颜色最大值
signed main(){
    int n;
    cin>>n;
    scanf("%s",s+1);
    int cnt=0;
    for(int i=1;i<=n;i++){
        int ma=0;
        for(int j=s[i]-'a'+1;j<26;j++){//前面比他大的字符的最大颜色
            ma=max(ma,d[j]);
        }
        d[s[i]-'a']=max(d[s[i]-'a'],ma+1);//更新最大颜色
        ans[i]=max(d[s[i]-'a'],ma+1);//当前位置颜色
        cnt=max(ans[i],cnt);//更新颜色数量
    }
    cout<<cnt<<endl;
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<' ';
    }
    return 0;
}
公開された430元の記事 ウォン称賛36 ビュー20000 +

おすすめ

転載: blog.csdn.net/weixin_44178736/article/details/104561905