参考:https://www.cnblogs.com/Dup4/p/10635933.html
————————————————————————————————————
规则:
全部元素都要放进升序或者降序序列里面
就先考虑开头的两个数a b,假设a > b
那么应该怎么分呢?
直觉告诉我们,a放到降序,b放到升序
如果不这样做呢?a放到升序,b放到降序
那么后面的数的选择空间就变小了
如图所示:左边是更优的选择。
#include<bits/stdc++.h>
using namespace std;
#define sc scanf
#define pt printf
#define maxn 200005
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<b;++i)
int x[maxn],used[maxn];
vector<int> a,b;
int main()
{
//1是降序,0是升序
//freopen("in.txt","r",stdin);
int n;
sc("%d",&n);
rep(i,0,n) sc("%d",&x[i]);
a.push_back(-1); b.push_back(inf);
rep(i,0,n)
{
int p = a.back(), q=b.back();
if(x[i]<=p&&x[i]>=q)
{
pt("NO\n");
return 0;
}
//这里有个比较神奇的地方,升序要比前一个大,但是会分成两部分考虑
if(x[i]>p&&x[i]<q) //两个序列都能去
{
if(i+1==n)//是最后一个
{
used[i] = 0; //让它默认插到升序序列那里
}
else
{
if(x[i]<=x[i+1]) //现在的数小与或者等于后面的数,插到升序序列
{
a.push_back(x[i]);
used[i] = 0;
}
else //现在的数比后面的数大,插到降序序列
{
b.push_back(x[i]);
used[i] = 1;
}
}
}
else if(x[i]>p&&x[i]>=q) //只能去升序序列
{
a.push_back(x[i]);
used[i] = 0;
}
else if(x[i]<=p&&x[i]<q) //只能去降序序列
{
b.push_back(x[i]);
used[i] = 1;
}
//pt("%d %d %d\n",x[i],p,q);
}
pt("YES\n");
rep(i,0,n) pt("%d%c",used[i]," \n"[i==n-1]);
return 0;
}