题目:https://codeforces.com/problemset/problem/1144/G
题意:
将一个序列分成两个序列,两个序列中元素的相对顺序保持和原序列不变,使得分出的两个序列一个严格上升,一个严格下降。
思路:
对于第 i 个数 , 我们应该分析什么情况可以放入升序什么情况放入降序 ; 最容易的情况就是第 i 个数只能放在特定的一个序列中 , 与都不能放在序列中也就是 NO 的情况 ;
假如此时的 i 是可以放入升序与降序的时候 , 我们就用a[i] 与a[ i+1 ] 比较 , 如果 a[i] > a[i+1] 很显扬是把a[i] 放入到降序中 , 因为这样a[i+1] 如果不能放入升序则可以放到降序 中 ; a[i] < a[i+1] 反之 , 那如果a[i]==a[i+1] ,就两个序列分别进一个呗;
#include<bits/stdc++.h> using namespace std; vector<int>H; vector<int>L; int a[200001]; bool vis[200001]; int main() { int n;scanf("%d",&n); for(int i=1 ; i<=n ;i++) { scanf("%d",&a[i]); } bool T=0; for(int i=1 ; i<=n ; ) { bool faH=0 , faL=0; int tailH=H.size()-1 , tailL=L.size()-1; if(H.size()==0) faH=1; else if(H[tailH]<a[i]) faH=1; if(L.size()==0) faL=1; else if(L[tailL]>a[i]) faL=1; // printf("%d %d %d ",faH,faL,H.size()); if(faH==0&&faL==0) { T=1;break; } if(faH==0&&faL==1) { L.push_back(a[i]); vis[i]=1;i++; } if(faH==1&&faL==0) { H.push_back(a[i]); vis[i]=0; i++; } if(faH==1&&faL==1) { if(a[i]<a[i+1]) { H.push_back(a[i]); vis[i]=0;i++; } else if(a[i]>a[i+1]) { L.push_back(a[i]); vis[i]=1;i++; } else { H.push_back(a[i]); L.push_back(a[i+1]); vis[i]=0; vis[i+1]=1; i+=2; } } } if(T) puts("NO"); else { puts("YES"); for(int i=1 ; i<=n ; i++) { printf("%d ",vis[i]); } } }