7-5 快乐的尽头 (17 分)
7-5 快樂的盡頭 (17 分)
題目
快樂風(fēng)男面前有n個(gè)兵,呈線性排列編號(hào)為1~n,每個(gè)小兵攜帶a[i]個(gè)金幣1<=i<=1e5,為了體現(xiàn)快樂的極致,快樂風(fēng)男知道了每個(gè)小兵攜帶的金幣,快樂的他E往無前(也就是說他不會(huì)回頭),但是快樂的他每次e的小兵的金幣都嚴(yán)格遞增,為了他能快樂多一點(diǎn),請(qǐng)你給出他e兵的方案(上升子序列下標(biāo) 如樣例最長(zhǎng)上升子序列為1 2 3 4 ,你需要輸出其對(duì)應(yīng)的下標(biāo)1 2 3 5),讓他e的兵越多越好,如果有多個(gè)快樂方案,給出字典序最小1<=n<=100000
(由于原數(shù)據(jù)未分組,現(xiàn)在不需要讀入T,即每個(gè)數(shù)據(jù)一個(gè)案例)
輸入格式
第一行輸入n表示有n個(gè)小兵 第二行為每個(gè)小兵的攜帶金幣
輸出格式
第一行給出快樂風(fēng)男可以e的最大兵數(shù),第二行給出最佳方案
輸入樣例
5
1 2 3 3 4
輸出樣例
4
1 2 3 5
基本思路
這題的主要分為兩部分來看待。
第一部分是利用 貪心+二分法對(duì)初始序列的每個(gè)元素進(jìn)行處理。(這一步模板化,不難)
這個(gè)模板下面這篇文章介紹的很詳細(xì),可以先看一看,傳送門:
添加鏈接描述
第二部分是利用已有的信息倒推得出具體的LIS。(這一步很難理解,感覺也是這道題目的精髓所在)
可以先看我的代碼和代碼注釋(比較詳細(xì)),基礎(chǔ)比較好的同學(xué)應(yīng)該還是能夠理解的。
代碼
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; int maxLength;//最長(zhǎng)遞增子序列的長(zhǎng)度 int a[100001];//初始序列 int greedy[100001];//greedy[i]存放長(zhǎng)度為i的LIS的結(jié)尾元素的最小值。初始化為INF int posInLIS[100001];//下標(biāo)為a[i]的下標(biāo)i,值為如果a[i]被選中(作為L(zhǎng)IS的一部分),那么它在LIS中的位置 int firstAppear[100001]; int ans[100001];//下標(biāo)表示LIS中第幾個(gè)位置,值表示該位置上的元素在數(shù)組a中的下標(biāo) int main() {//讀入初始序列aint n;cin >> n;for (int i = 1; i <= n; i++)cin >> a[i];//初始化數(shù)組greedymemset(greedy, INF, sizeof(greedy));//枚舉a[i]從a[1]到a[n]for (int i = 1; i <= n; i++){//在數(shù)組greedy中找到第一個(gè)大于等于a[i]元素的下標(biāo)int indexInGreedy = lower_bound(greedy + 1, greedy + n + 1, a[i]) - greedy;//如果indexInGreedy為數(shù)組greedy最后一個(gè)元素的后一個(gè)位置下標(biāo),更新maxLengthif (greedy[indexInGreedy] == INF)maxLength++;//a[i]放到數(shù)組greedy的最后一個(gè)元素的后一個(gè)位置indexInGreedy//a[i]覆蓋原有的greedy[indexInGreedy]greedy[indexInGreedy] = a[i];//posInLIS[i]表示a[i]的indexInGreedy(如果a[i]被選中(作為L(zhǎng)IS的一部分),那么它在LIS中的位置)posInLIS[i] = indexInGreedy;/*firstAppear[indexInGreedy]記錄第一個(gè)計(jì)算結(jié)果為indexInGreedy的a[i]的下標(biāo)i用來求得最終的LIS的結(jié)尾元素在數(shù)組a中的下標(biāo)*/if (!firstAppear[indexInGreedy])firstAppear[indexInGreedy] = i;}//求出最終的LIS的每個(gè)元素在數(shù)組a中的下標(biāo)ans[maxLength] = firstAppear[maxLength];for (int indexIna = firstAppear[maxLength] - 1; indexIna >= 1; indexIna--) {if (a[indexIna] < a[ans[posInLIS[indexIna] + 1]])ans[posInLIS[indexIna]] = indexIna;}//輸出cout<<maxLength<<endl;for(int i=1;i<=maxLength;i++)cout<<(i==1?"":" ")<<ans[i];return 0; }總結(jié)
以上是生活随笔為你收集整理的7-5 快乐的尽头 (17 分)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 抗乙型肝炎表面抗原(HBsAg)抗体偶联
- 下一篇: 纳米压印光刻技术展望