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

链接: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\n", 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?'\n':' ');
}

 

 

 

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

#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\n", 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?'\n':' ');
}

 

posted @ 2021-01-16 18:36  哎呦哎(iui)  阅读(645)  评论(0编辑  收藏  举报