選擇子串行 51Nod 1153

2021-08-07 21:41:00 字數 1300 閱讀 3174

長度為n的整數陣列a,所有的數均不相同,假設下標從0開始。找到乙個最長的陣列b,b陣列的長度為k,數值範圍是0 - n - 1,記錄的是a陣列的下標。滿足ab[

0 ] > ab[

1 ] > ab[

2 ] >...ab[

k ],並且對任意連續的兩項b

i 及bi+

1 ,滿足min(b

i ,bi+

1 ) < j < max(b

i ,bi+

1 ) 均有aj

< ab[

i+1

] ,求最大的k。例如:9, 10, 2, -1, 3, -5, 0, -3, 1, 12, 5, 8, -2, 6, 4。可以選出:12, 10, 3, 1, 0, -3。對應的下標為:9, 1, 4, 8, 6, 7(就是b陣列),輸出6。

input

第1行:乙個數n,表示a陣列的長度。(1 <= n <= 50000)

第2 - n + 1行:每行1個數對應a陣列的元素ai(0 < ai < 10^9)

output

輸出b陣列最長的長度k。

sample input

15910

2-13-5

0-3112

58-26

4

sample output

6

一道單調棧的題,具有這種「阻止」的特徵,就是說不能越界的特點,我們的棧中正好保留著那些可能的隔離點。

#include #includeusing namespace std;

const int maxn=50010;

stackstk;

struct nodes[maxn];

int max_val(int a,int b)

/*乙個單調棧的問題,現在想想可能有點感覺了,要求 l~r,中間的值都小於兩邊的值,

這就很像單調棧的問題,就是保留乙個連續的遞減的序列,中間進行一些操作

只保留那些高的點

*/int main()

else

}temp_len++;

temp_len=max_val(temp_len,stk.size()+1);//注意這裡,乙個是我們進行中間的」精簡「,還有就是保留的遞減序列

s[i].max_len=temp_len;

ans=max(ans,s[i].max_len);

stk.push(i);

}printf("%d\n",ans);

}

51nod 1153 選擇子串行

長度為n的整數陣列a,所有的數均不相同,假設下標從0開始。找到乙個最長的陣列b,b陣列的長度為k,數值範圍是0 n 1,記錄的是a陣列的下標。滿足a b 0 a b 1 a b 2 a b k 並且對任意連續的兩項b i 及b i 1 滿足min b i b i 1 j max b i b i 1 ...

51nod 1153 選擇子串行

51nod 選擇子串行 這道題是 bunny 學長在給我們的模擬賽中的一道題。食用單調棧,處理每個數 a i 左右第乙個比自己大的數的下標 left i right i 並且建兩條有向邊 i,left i i,right i 處理完畢後得到乙個 dag 然後求此圖的拓撲序。由於都是小數連大數,所以可...

51nod 1153 選擇子串行 (好題)

這個題很不錯。採用貪心的思想 首先考慮到在整個序列中取最大值一定是最優的,也就是說b陣列的第乙個數是a陣列的中最大值的下標。而且通過題意我們發現,一旦選定了某個數就把當前的區間劃分成兩份。比如說第一次選了9,第二次選了10,那麼下一次肯定不會選8 這幾個數字說的都是下標 不會垮區間選數,那麼我們就可...