Wannafly Winter Camp 2020 Day 6G 单调栈

对于排列 (p),它的单调栈 (f) 定义为,(f_i) 是以 (p_i) 结尾的最长上升子序列的长度

先给定 (f) 中一些位置的值,求字典序最小的 (p) 使得它满足这些值

Solution

显然 (f[1]=1),考虑所有满足 (f[x]=1) 的位置 (b_1,dots,b_k),一定有 (p_{b_1}>p_{b_2}>dots >p_{b_k})

由于 (b_1=1),我们要最小化 (p_1),所以填入 (p_{b_i}=k-i+1)

然后考虑所有 (f[x]=2) 的数,同理操作(注意第一个数仍然为最小),填入值加一个偏移即可

最后,对于 (f) 值没有给出的那些数,从左到右从小到大填入即可

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

const int N = 105;
int n,t,s,f[N],p[N];

signed main() {
    ios::sync_with_stdio(false);
    cin>>t;
    while(t--) {
        cin>>n;
        for(int i=1;i<=n;i++) cin>>f[i];
        int sum=0;
        memset(p,0,sizeof p);
        for(int i=1;i<=n;i++) {
            stack<int> v;
            for(int j=1;j<=n;j++) if(p[j]==0) {
                f[j]=i;break;
            }
            for(int j=1;j<=n;j++) if(f[j]==i) v.push(j);
            while(v.size()) p[v.top()]=++sum, v.pop();
        }
        for(int i=1;i<=n;i++) if(p[i]==0) p[i]=++sum;
        for(int i=1;i<=n;i++) cout<<p[i]<<(n==i?"":" ");
        cout<<endl;
    }
}

原文地址:https://www.cnblogs.com/mollnn/p/12365070.html