[codeforces 1296E2] String Coloring (hard version) 很牛的最长上升子序列的写法+还能记录子序列中的元素

[codeforces 1296E2] String Coloring (hard version) 很牛的最长上升子序列的写法+还能记录子序列中的元素

总目录详见https://blog.csdn.net/mrcrack/article/details/103564004

在线测评地址https://codeforces.ml/contest/1296/problem/E2

Problem Lang Verdict Time Memory
E2 - String Coloring (hard version) GNU C++11 Accepted 46 ms 800 KB

//将e1的思路用在e2上,先不论超时,就是感觉有些混乱。
//根据题目提供的数据范畴,能猜到算法的时间复杂度是O(26*n). 26个字母
//思路同https://blog.csdn.net/caowenbo2311694605/article/details/104181983摘抄如下
/*
可以想出其实本题就是请你找出
有多少个非递减子序列(最小)
很简单最多有26个 因为只有26个字母
我一开始的考虑是每次找最长非递减子序列 然后去掉 再找
最多找26次 但是我不会输出最长非递减子序列的元素
后来看了下别人的代码(发现贪心的考虑是多余的)
然后就很简单了
直接把每个元素放入能放的序列就好了(cf的tag太坑了)
*/
//算法写得很不错,比一般编程模板介绍的最长上升子序列的写法要牛。若看不懂,可跟踪代码。

#include <stdio.h>
#define maxn 200010
char s[maxn],pre[30];
int color[maxn];
int max(int a,int b){
	return a>b?a:b;
}
int main(){
	int i,j,n,ans=0;
	scanf("%d%s",&n,s+1);
	for(i=1;i<=n;i++)
		for(j=1;j<=26;j++)//26个字母,故颜色最大值最多是26
			if(s[i]>=pre[j]){//s[i]当前值要比 之前值 大或等于
				pre[j]=s[i],color[i]=j,ans=max(ans,j);
				break;
			}
	printf("%d\n%d",ans,color[1]);
	for(i=2;i<=n;i++)printf(" %d",color[i]);
	printf("\n");
	return 0;
}
发布了537 篇原创文章 · 获赞 529 · 访问量 44万+

猜你喜欢

转载自blog.csdn.net/mrcrack/article/details/104287520
今日推荐