String Coloring (Easy&Hard)

https://codeforces.com/contest/1296/problem/E1

https://codeforces.com/contest/1296/problem/E2


This is an easy version of the problem. The actual problems are different, but the easy version is almost a subtask of the hard version. Note that the constraints and the output format are different.

You are given a string ss consisting of nn lowercase Latin letters.

You have to color all its characters one of the two colors (each character to exactly one color, the same letters can be colored the same or different colors, i.e. you can choose exactly one color for each index in ss).

After coloring, you can swap any two neighboring characters of the string that are colored different colors. You can perform such an operation arbitrary (possibly, zero) number of times.

The goal is to make the string sorted, i.e. all characters should be in alphabetical order.

Your task is to say if it is possible to color the given string so that after coloring it can become sorted by some sequence of swaps. Note that you have to restore only coloring, not the sequence of swaps.

Input

The first line of the input contains one integer nn (1≤n≤2001≤n≤200) — the length of ss.

The second line of the input contains the string ss consisting of exactly nn lowercase Latin letters.

Output

If it is impossible to color the given string so that after coloring it can become sorted by some sequence of swaps, print "NO" (without quotes) in the first line.

Otherwise, print "YES" in the first line and any correct coloring in the second line (the coloring is the string consisting of nn characters, the ii-th character should be '0' if the ii-th character is colored the first color and '1' otherwise).

Examples

input

Copy

9
abacbecfd

output

Copy

YES
001010101

input

Copy

8
aaabbcbb

output

Copy

YES
01011011

input

Copy

7
abcdedc

output

Copy

NO

input

Copy

5
abcde

output

Copy

YES
00000

思路:开始自己模拟了半天有点头绪然后发现很难写。这道题其实和之前做到的cf一道也是移动相邻的有点像,那题最后是用归并的思路去模拟的。

写这道题要发现

比如 o o o  o o

        1 2 2  1  1

那我随意调换顺序,可能会有 1 2 1 2 1,或者1 2 2 1 1 或者2 2 1 1 1 总之可以有很多种变换。但是不管怎么变换,同样颜色之间的相对顺序是没法变的,这是关键也是核心。比如1 2  2  1 1的前面2 是d,后面2是a,无论如何这个a到不了d的前面去,这就是无解的情况。

所以发现了每个相同颜色内必须要保证不下降序列之后,根据题意看能不能划分出两条不下降序列就好了,如果有第三条就是NO。记录一下两条末尾的最大值,然后新进来的看能放哪边就放进去,不能放就只能第三种颜色就gg了。


hard版本题意:

给你一串长度为 n 的字符串,你可以给每个位置上染上一种不大于 n 的颜色

对于相邻的两个位置,如果他们的颜色不同则可以交换他们的位置

现在需要交换若干次后按照字典序排序

你需要找到最少满足条件的颜色数并输出方案


好经过上面的分析,可以看出这题就是问你最少用几个不下降子序列,并输出方案数。当然如果你做过导弹拦截的话会知道离散数学的一个定理:这个不下降子序列的个数等于最长上升子序列的长度。

当然这题不必要用这个dp。还是仿照easy版本去模拟就好了。不停去涂颜色直到整个序列涂满了就结束了。

平均复杂度在O(n)带个常数把

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef long long LL;
char s[maxn];
bool vis[maxn];
LL a[maxn],n;
void solve()
{
	cin>>(s+1);
	LL ans=0;LL len=0;LL cnt=1;
	while(len<n)
	{
		LL mx=0;
		for(LL i=1;i<=n;i++)
		{
			if(s[i]-'0'>=mx&&!vis[i])
			{
				len++;
				mx=s[i]-'0';
				vis[i]=true;
				a[i]=cnt;	
			}
		}
		cnt++;
		ans++;
	}
	cout<<ans<<endl;
	for(LL i=1;i<=n;i++) cout<<a[i]<<" ";
	cout<<endl;
}
int main(void)
{
  cin>>n;
  solve();
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108339924
今日推荐