zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
    
  • 相关阅读:
    Linux之Shell编程read读取控制台输入
    Linux之Shell编程while循环基本使用
    Linux之Shell编程for循环基本使用
    Linux之Shell编程case语句
    C语言 ##__VA_ARGS__
    C语言 __VA_ARGS__
    C语言 ##运算符
    C语言 __cplusplus
    C语言 #运算符
    C语言 extern “C”
  • 原文地址:https://www.cnblogs.com/mollnn/p/12365070.html
Copyright © 2011-2022 走看看