• BZOJ1046 [HAOI2007]上升序列


    啊,noip难度题。。。蒟蒻调了半天。。。

    嘛、先是求LIS的长度,O(n * logn)算法大家都会

    然后就是贪心,假设我们找到了答案的第x项,向后找第x + 1项:

    我们发现,只需找当前最前面的a[i]满足f[i] >= l - x的即可。

     1 /**************************************************************
     2     Problem: 1046
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:1772 ms
     7     Memory:960 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <algorithm>
    12  
    13 using namespace std;
    14 const int N = 10005;
    15 const int inf = (int) 1e9;
    16 int f[N], a[N], b[N];
    17 int len, n;
    18 int ans[N];
    19  
    20 inline int read(){
    21     int x = 0, sgn = 1;
    22     char ch = getchar();
    23     while (ch < '0' || ch > '9'){
    24         if (ch == '-') sgn = -1;
    25         ch = getchar();
    26     }
    27     while (ch >= '0' && ch <= '9'){
    28         x = x * 10 + ch - '0';
    29         ch = getchar();
    30     }
    31     return sgn * x;
    32 }
    33  
    34 void pre_work(){
    35     len = 1;
    36     int l, r, mid;
    37     for (int i = 2; i <= n; ++i)
    38         b[i] = -inf;
    39     b[0]= inf, b[1] = a[1], f[1] = 1;
    40     for (int i = 2; i <= n; ++i){
    41         l = 0, r = len + 1;
    42         while (l + 1 < r){
    43             mid = (l + r) >> 1;
    44             if (b[mid] > a[i]) l = mid;
    45             else r = mid;
    46         }
    47         len = max(len, ++l);
    48         b[l] = max(b[l], a[i]);
    49         f[i] = l;
    50     }
    51     reverse(a + 1, a + n + 1);
    52     reverse(f + 1, f + n + 1);
    53 }
    54  
    55 void work(int l){
    56     if (len < l){
    57         printf("Impossible
    ");
    58         return;
    59     }
    60     int cnt = 0, last = -inf;
    61     for (int i = 1; i <= n && l != 0; ++i)
    62         if (f[i] >= l && a[i] > last)
    63             ans[++cnt] = i, --l, last = a[i];
    64     for (int i = 1; i < cnt; ++i)
    65         printf("%d ", a[ans[i]]);
    66     printf("%d
    ", a[ans[cnt]]);
    67 }
    68  
    69 int main(){
    70     n = read();
    71     for (int i = n; i; --i)
    72         a[i] = read();
    73     pre_work();
    74     int m = read(), X;
    75     while (m--){
    76         X = read();
    77         work(X);
    78     }
    79     return 0;
    80 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    python实现矩阵的点乘,转置与求逆
    C#用嵌套的 for 循环实现打印图形
    visual studio 2019的安装方法
    人工智能之python实现函数微积分
    人工智能之python实现矩阵运算
    人工智能之实现简单神经网络之数据解析和可视化
    人工智能之实现简单神经网络之权重更新算法
    ubuntu服务器版相关命令
    php的windows各版本客户端下载
    谷歌快捷工具地址
  • 原文地址:https://www.cnblogs.com/rausen/p/4050818.html
Copyright © 2020-2023  润新知