• Codeforces 1144G Two Merged Sequences


    题意:

    将一个序列分成两个序列,两个序列中元素的相对顺序保持和原序列不变,使得分出的两个序列一个严格上升,一个严格下降。

    思路:

    我们考虑每个元素都要进入其中一个序列。

    那么我们维护一个上升序列和一个下降序列,对于当前元素$i$:

    如果它只能确定的进入一个序列,那么就让它进入。

    如果它一个序列也进不去,那么答案就是'NO'。

    如果它两个序列都可以进去,那么判断它和后一个元素(如果存在的话)的关系,如果它后一个元素比它大,那么让它进去上升序列,否则进去下降序列。

    考虑这样为什么是对的:

    首先我们知道一个存在答案的序列里面的元素重复度最大是$2$,那么对于上述的第三种操作,我们考虑一种最特殊的情况,

    就是对于第一个元素的判断,它显然可以进入任意一个序列,但是至于让它进入哪个序列,我们不知道。

    但是一个比较直观的感觉是,如果它和剩下的数相比相对来说是较大的,我们倾向于让它进入下降序列,反之,进入上升序列

    那么其实不用跟剩下的所有数比,只需要让它和后一个数比一下即可。

    因为这一步比较,相当于让这个数强行接在后一个数的前面,可以等价于去掉这个数,(做不了选择就不做选择了嘛

    但是后一个数跟它相等怎么办?

    相等,就两个序列分别进一个呗。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 200010
     5 #define INF 0x3f3f3f3f
     6 int n, arr[N];
     7 vector <int> A, B;
     8 int used[N];
     9 
    10 void solve()
    11 {
    12     A.clear(), B.clear();
    13     memset(used, 0, sizeof used); 
    14     A.push_back(-1);
    15     B.push_back(INF);
    16     for (int i = 1; i <= n; ++i)
    17     {
    18         int x = arr[i], a = A.back(), b = B.back(), y;
    19         if (x <= a && x >= b)
    20         {
    21             puts("NO");
    22             return;
    23         }
    24         else if (x > a && x < b)
    25         {
    26             if (i == n) 
    27                 used[i] = 1;
    28             else
    29             {
    30                 y = arr[i + 1];
    31                 if (y > x)
    32                     A.push_back(x);
    33                 else
    34                 {
    35                     B.push_back(x);
    36                     used[i] = 1;
    37                 }
    38             }
    39         }
    40         else if (x > a)
    41             A.push_back(x);
    42         else
    43         {
    44             used[i] = 1;
    45             B.push_back(x);
    46         }
    47     }
    48     puts("YES");
    49     for (int i = 1; i <= n; ++i)
    50         printf("%d%c", used[i], " 
    "[i == n]);
    51 }
    52 
    53 int main()
    54 {
    55     while (scanf("%d", &n) != EOF)
    56     {
    57         for (int i = 1; i <= n; ++i) scanf("%d", arr + i);
    58         solve();
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    检索通讯录,根据输入的电话号码的每一位下拉显示检索结果
    获取手机的具体型号 及 iOS版本号
    在iOS中使用ZBar扫描二维码
    iOS沙盒路径的查看和使用
    ios打开通讯录及点击通讯录时提取相关信息
    获取倒计时距离某一时间点的时间,判断身份证,电话号码格式是否正确的简单封装
    iOS 获取手机的型号,系统版本,软件名称,软件版本
    第三天战略会议
    第二天站略会议总结
    第一天站略会议总结
  • 原文地址:https://www.cnblogs.com/Dup4/p/10635933.html
Copyright © 2020-2023  润新知