LIS+贪心

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

bzoj1046_dpbzoj1046_字典序_02
#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\n", ans[ans.size() - 1]);
        }
    }
//    fclose(stdin);
//    fclose(stdout);
    return 0;
}
View Code