鏈接:https://ac.nowcoder.com/acm/contest/3282/G?&headNav=acm
來源:牛客網
Hasaki!lfqlfqlfq 特別喜歡玩快樂風男,並且他喜歡無縫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
說明
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':' '); }
