• 输出最长上升子序列的方案


    链接:https://ac.nowcoder.com/acm/contest/3282/G?&headNav=acm
    来源:牛客网

    Hasakilfqlfqlfq 特别喜欢玩快乐风男,并且他喜欢无缝E的感觉。

    现在 lfqlfqlfq 面前有n个兵,呈线性排列编号为 1−n,每个小兵携带 ai 个金币。为了体现快乐的极致, lfqlfqlfq 知道了每个小兵携带的金币,快乐的他E往无前(也就是说他不会回头),但是快乐的他每次E的小兵的金币都严格递增,为了 lfqlfqlfq 能E到更多的小兵,请你给出他E兵的编号。如果有多个快乐方案,给出字典序最小的方案

    输入描述:

    第一行一个整数 n(1<=n<=1e5),表示小兵的个数。

    接下来一行 n 个整数,a1,a2,…an,(1<=ai<=1e5)n(1<=ai<=1e5)表示编号为i的小兵所携带的金币数量。

    输出描述:

    第一行输出一个整数 kkk,表示 lfqlfqlfq 最多能E到小兵的个数。

    接下来一行输出 kkk 个整数,表示 lfqlfqlfq 能E到的小兵的下标。行末不要加空格。

    示例1

    输入

    复制
    5
    1 2 4 3 5

    输出

    复制
    4
    1 2 3 5

    说明

    lfqlfqlfq 有两种E到4个小兵的方案,1 2 3 5 和 1 2 4 5,其中下标1 2 3 5的字典序小于1 2 4 5,所以答案是1 2 3 5

    这个题让输出的下标的字典序最小,

    https://www.cnblogs.com/xwdzuishuai/p/12081775.html

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    
    int n;
    int a[N], cnt, f[N];
    
    int len[N], first[N];
    int ans[N];
    
    int main()
    {
        memset(f, 0x3f, sizeof(f));
        scanf("%d", &n);
        for (int i = 1; i <= n; i ++)
            scanf("%d", &a[i]);
        for (int i = 1; i <= n; i ++)
        {
            int t = lower_bound(f + 1, f + n + 1, a[i]) - f;
            if(f[t] == INF)
            {
                ++ cnt;
                f[t] = a[i];
                len[i] = t;
            }
            else
            {
                f[t] = a[i];
                len[i] = t;
            }
            if(first[len[i]] == 0) first[len[i]] = i;
        }
        printf("%d
    ", cnt);
        ans[cnt] = first[cnt];
        for (int i = first[cnt] - 1; i >= 1; i --)
        {
            if(a[i] < a[ans[len[i] + 1]])
            ans[len[i]] = i;
         }
        for(int i = 1; i <= cnt; i++)
        printf("%d%c", ans[i], i==cnt?'
    ':' ');
    }

    如果输出数的字典序最小的下标的话

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    const int INF = 0x3f3f3f3f;
    
    int n;
    int a[N], cnt, f[N];
    
    int len[N], first[N];
    int ans[N];
    
    int main()
    {
        memset(f, 0x3f, sizeof(f));
        scanf("%d", &n);
        for (int i = 1; i <= n; i ++)
            scanf("%d", &a[i]);
        for (int i = 1; i <= n; i ++)
        {
            int t = lower_bound(f + 1, f + n + 1, a[i]) - f;
            if(f[t] == INF)
            {
                ++ cnt;
                f[t] = a[i];
                len[i] = t;
            }
            else
            {
                f[t] = a[i];
                len[i] = t;
            }
            first[len[i]] = i;
        }
        printf("%d
    ", cnt);
        ans[cnt] = first[cnt];
        for (int i = first[cnt] - 1; i >= 1; i --)
        {
            if(a[i] < a[ans[len[i] + 1]])
            ans[len[i]] = i;
         }
        for(int i = 1; i <= cnt; i++)
        printf("%d%c", ans[i], i==cnt?'
    ':' ');
    }
  • 相关阅读:
    扫盲如何在ECLIPSE中使用条件断点
    春困
    气虚咳喘案
    知足老师论糖尿病
    辨痰之病位与寒热
    常用中药功效比较(任之堂)
    女子全身窜痛案
    小儿外感案
    紫斑案
    读任之堂中药讲记笔记
  • 原文地址:https://www.cnblogs.com/lipu123/p/14286890.html
Copyright © 2020-2023  润新知