CodeForces - 486E LIS of Sequence

对于每个点求出开头到该点的最长上升子序列长度==以及该点到结尾的最长上升子序列长度

(该点都强制使用)记为dp1和dp2

于是如果dp1[i]+dp2[i]-1与LIS的长度相等 则该点为2或3否则为1

对于不是1的点如果有别的点与它dp1相同则为2(即可以选该点也可以选别的相同的点)否则为3


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define rep(j,k,l) for (int j=k;j<=l;j++)
#define N 100010

using namespace std;
int stk[N],a[N],dp1[N],dp2[N],ans[N],wzf[N],len,n;

int read(){
	
	char ch=getchar();
	while (ch<'0'||ch>'9') ch=getchar();
	int k=ch-48;
	while (1){
		
		ch=getchar();
		if (ch<'0'||ch>'9') return k;
		k=k*10+ch-48;
		
	}
	
}

int main(){
	
	int n=read();
	rep(i,1,n) a[i]=read();
	int top=0;
	rep(i,1,n){
		
		if (a[i]>stk[top]) stk[++top]=a[i],dp1[i]=top;
		else{
			
			int k=top;
			while (a[i]<=stk[k-1]) k--;
			stk[k]=a[i];
			dp1[i]=k;
			
		}
		
	}
	rep(i,1,n/2) swap(a[i],a[n-i+1]);
	len=top;top=0;stk[0]=N;
	rep(i,1,n){
		
		if (a[i]<stk[top]) stk[++top]=a[i],dp2[n-i+1]=top;
		else{
			
			int k=top;
			while (a[i]>=stk[k-1]) k--;
			stk[k]=a[i];
			dp2[n-i+1]=k;
			
		}
		
	}
	rep(i,1,n) if (dp1[i]+dp2[i]<len+1) ans[i]=1;
	top=0;
	rep(i,1,n) if (ans[i]!=1){
		
		if (wzf[dp1[i]]==0){
			
			ans[i]=3;
			wzf[dp1[i]]=i;
			
		}else ans[wzf[dp1[i]]]=ans[i]=2;
		
	}
	rep(i,1,n) printf("%d",ans[i]);
	puts("");
	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值