其他分享
首页 > 其他分享> > [HAOI2007] 上升序列 - dp,贪心

[HAOI2007] 上升序列 - dp,贪心

作者:互联网

给定序列 \(S\),有 \(m\) 次询问,每次要求输出下标字典序最小的长度为 \(l_i\) 的上升序列

Solution

考虑设 \(f[i]\) 表示从 \(i\) 发出的最长上升子序列的长度,倒序转移$

转移时,在使得 \(f[i]\) 最大的情况下,使得 \(i\) 尽量小,即可使得字典序最小

每次询问时,检查是否有 \(f[i]=l\),如果没有则直接判定无解

否则,从头开始,利用已经预处理出的 \(f[i]\) 数组,贪心地找出一个下标字典序最小的上升序列即可

(一开始想着记录转移数组来输出答案,后来发现我憨了)

#include <bits/stdc++.h>
using namespace std;

const int N = 1000005;
int n,m,a[N],f[N],l;

signed main() {
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=n;i>=1;--i) {
        f[i]=1;
        for(int j=i+1;j<=n;j++) {
            if(a[i]<a[j]) {
                if(f[i]<f[j]+1) f[i]=f[j]+1;
            }
        }
    }
    cin>>m;
    while(m--) {
        cin>>l;
        int t=0;
        for(int i=1;i<=n;i++) {
            if(f[i]==l) t=i;
        }
        if(t==0) cout<<"Impossible"<<endl;
        else {
            int lim=0;
            for(int i=1;i<=n;i++) if(l && f[i]>=l && a[i]>lim) {
                cout<<a[i]<<" ";
                lim=a[i];
                --l;
            }
            cout<<endl;
        }
    }
}

标签:下标,int,cin,HAOI2007,序列,贪心,dp,字典
来源: https://www.cnblogs.com/mollnn/p/12381477.html