1144G Two Merged Sequences ( 贪心+构造)

题目: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\n",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]);
       }

    }
}
View Code

参考:https://www.cnblogs.com/Dup4/p/10635933.html

猜你喜欢

转载自www.cnblogs.com/shuaihui520/p/10638310.html