#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAXN 100000
#define INF 0x3f3f3f3f
int a[MAXN +10];
int num[2][MAXN +10];
int sum[MAXN +10];
int n;
using namespace std;
int lis(int *a,int *num)
{
int d[MAXN +10];
memset(d,0x3f,sizeof(d));
int len = 0,i,k;
for(i = 1;i <= n;i++)
{
k = lower_bound(d+1,d+n+1,a[i])-d;
num[i] = k;
if(d[k] == INF)
len++;
d[k] = a[i];
}
return len;
}
int anti_sis(int *a,int *num)
{
int len = 0,i,k;
int d[MAXN +10];
memset(d,0x3f,sizeof(d));
for(i = 1;i <= n;i++)
a[i] = -a[i];
for(i = n;i >= 1;i--)
{
k = lower_bound(d+1,d+n+1,a[i])-d;
num[i] = k;
if(d[k] == INF)
len++;
d[k] = a[i];
}
return len;
}
int main()
{
int i;
scanf("%d",&n);
for(i = 1;i <= n;i++)
scanf("%d",&a[i]);
int len = lis(a,num[0]);
int len1 = anti_sis(a,num[1]);
for(i = 1;i <= n;i++)
if(num[0][i] + num[1][i] > len)
sum[num[0][i]]++;
for(i = 1;i <= n;i++)
if(num[0][i] + num[1][i] <= len)
printf("1");
else if(sum[num[0][i]] == 1)
printf("3");
else
printf("2");
return 0;
}
/*
4
1 3 2 5
*/
题目大意,给出n个数字。
对于每个数字:
不属于任何一个Lis 1
属于多个一个Lis 2
属于任何一个Lis 3
先做最长上升子序列,再倒过来做一次最长下降(倒着做)。
就可以得到以这个数为结尾的序列长度,和这个数作为开头的序列长度。
下面贴出代码。