• bzoj1046


    LIS+贪心

    因为是要字典序尽量的小,但是如果我们从头做,就无法判断选了这个是否能够>=l,那么我们倒着跑一遍LDS,然后每次从尾部贪心,如果这个能选就选,判断标准是cnt+dp[i]>=l,就是已经选的加上这个的LDS比L大就是可以选。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 10010;
    int n, m;
    int dp[N], tree[10000010], last[N], a[N];
    int query(int l, int r, int x, int a, int b)
    {
        if(l > b || r < a) return 0;
        if(l >= a && r <= b) return tree[x];
        int mid = (l + r) >> 1, i = query(l, mid, x << 1, a, b), j = query(mid + 1, r, x << 1 | 1, a, b);
        if(dp[i] > dp[j]) return i;
        else if(dp[i] < dp[j]) return j;
        else return i > j ? i : j;
    }
    void update(int l, int r, int x, int pos, int i)
    {
        if(l == r) 
        {
            if(dp[i] > dp[tree[x]] || (dp[i] == tree[x] && i > tree[x])) tree[x] = i;         
            return;
        }
        int mid = (l + r) >> 1;
        if(pos <= mid) update(l, mid, x << 1, pos, i);
        else update(mid + 1, r, x << 1 | 1, pos, i);
        if(dp[tree[x << 1]] > dp[tree[x << 1 | 1]]) tree[x] = tree[x << 1];
        else if(dp[tree[x << 1 | 1]] > dp[tree[x << 1]])tree[x] = tree[x << 1 | 1];
        else tree[x] = tree[x << 1] > tree[x << 1 | 1] ? tree[x << 1] : tree[x << 1 | 1];
    }
    int main()
    {
    //    freopen("lis.in", "r", stdin);
    //    freopen("lis.out", "w", stdout);
        scanf("%d", &n);
        int m = 0;
        for(int i = 1; i <= n; ++i)    
        {
            scanf("%d", &a[i]);
            m = max(m, a[i]);
        }
        reverse(a + 1, a + n + 1);
        for(int i = 1; i <= n; ++i)
        {
            int j = query(1, m, 1, a[i] + 1, m);
            dp[i] = dp[j] + 1;
            update(1, m, 1, a[i], i);
            last[i] = j;
        }
        scanf("%d", &m);
        while(m--)
        {
            int l, val = 0, cnt = 0;
            scanf("%d", &l);
            vector<int> ans;
            for(int i = n; i && cnt < l; --i) if(dp[i] + cnt >= l && val < a[i])
            {
                val = a[i];
                ++cnt;
                ans.push_back(a[i]);
            }
            if(cnt == 0) puts("Impossible");
            else  
            {
                for(int i = 0; i < ans.size() - 1; ++i) printf("%d ", ans[i]);
                printf("%d
    ", ans[ans.size() - 1]);
            }
        }
    //    fclose(stdin);
    //    fclose(stdout);
        return 0;
    }
    View Code
  • 相关阅读:
    JS中常见的几种控制台台报错
    nssm常用命令(在Windows系统下安装服务的工具)
    Web前端浏览器默认样式重置(CSS Tools: Reset CSS)
    Layui的本地存储方法-Layui.data的基本使用
    JS事件冒泡与事件捕获怎么理解?
    解决Web开发HTML页面中footer保持在页面底部问题
    cpdetector获取文件编码
    maven
    jdom工具类
    httpclient4封装类
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7365125.html
Copyright © 2020-2023  润新知