輸出最長上升子序列的方案


鏈接: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':' ');
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM