[CF486E] LIS of Sequence && DP

计算从左往右的最长上升子序列 L 在计算从右往左的最长下降子序列 R

如果L[i] + R[i] - 1 < 最长上升子序列的长度 那么就一个都不是

否则统计长度为 i 的子序列位置的个数(满足在最长上升子序列内) 如果有且仅有一个长度为i的位置 那就是每一个子序列都包含

其他的就是至少一个

#include<cstdio>    
#include<algorithm>    
#include<cstring>    
#include<vector>    
#include<queue>  
#include<deque>
#include<iostream>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 100000;
int A[MAXN+10], d[MAXN+10], Inc[MAXN+10], Dec[MAXN+10], ans[MAXN+10], cnt[MAXN+10];
int n, m, inc, decrease;
void dp()
{
	memset(d, 0x3f, sizeof(d));
	for(int i = 1; i <= n; i++) {
		int pos = lower_bound(d+1, d+n+1, A[i]) - d;
		Inc[i] = pos; 
		if(d[pos] == d[0]) inc++;
		d[pos] = A[i];
	}
	memset(d, 0x3f, sizeof(d));
	for(int i = n; i > 0; i--) {
		int pos = lower_bound(d+1, d+n+1, -A[i]) - d;
		Dec[i] = pos; d[pos] = -A[i];
	}
}
int main()
{
	SF("%d", &n);
	for(int i = 1; i <= n; i++) SF("%d", &A[i]);
	dp();
	for(int i = 1; i <= n; i++) {
		if(Inc[i] + Dec[i] - 1 < inc) ans[i] = 1;
		else cnt[Inc[i]]++;
	}
	for(int i = 1; i <= n; i++) {
		if(ans[i]) PF("1");
		else if(cnt[Inc[i]] == 1) PF("3");
		else PF("2");
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值