質問の意味:
長さの文字列の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;
}