题意:
找出输入字符串的上升子序列的个数,简单版本中,个数大于两种就输出NO,小于两种输出YES,并且输出染色结果。困难版本输出上升子序列的个数,并输出染色结果。
思路:
简单版本:
一遍遍找最长上升子序列,不同的上升子序列左右交换后使得整个字符串变成上升的。如果个数大于两个就输出NO,否则输出YES和染色结果。
困难版本:
思路更简单,找出上升子序列的个数就行了。
代码:
//简单版
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,i,done=0,cur=0;
char mx;
string s;
cin>>n>>s;
vector<int> ans(n,-1);
while(done<n){
mx='a';
if(cur>1){
cout<<"NO";
return 0;
}
for(i=0;i<n;i++){
if(ans[i]==-1&&s[i]>=mx){//还没成为上升子序列,并且大于等于上升子序列尾巴的元素
mx=s[i];//更新尾巴
done++;//已染色的元素个数
ans[i]=cur;
}
}
cur++;
}
cout<<"YES\n";
for(i=0;i<n;i++)
cout<<ans[i];
return 0;
}
//困难版本
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,i,done=0,cur=1;
char mx;
string s;
cin>>n>>s;
vector<int> ans(n,-1);
while(done<n){
mx='a';
for(i=0;i<n;i++){
if(ans[i]==-1&&s[i]>=mx){
mx=s[i];
done++;
ans[i]=cur;
}
}
cur++;
}
cout<<cur-1<<endl;
for(i=0;i<n;i++)
cout<<ans[i]<<" ";
return 0;
}