洛谷P1901 發射站(單調棧)

2021-10-02 07:22:32 字數 3195 閱讀 7301

某地有 n 個能量發射站排成一行,每個發射站 i 都有不相同的高度 hi,並能向兩邊(當 然兩端的只能向一邊)同時發射能量值為 vi 的能量,並且發出的能量只被兩邊最近的且比 它高的發射站接收。

顯然,每個發射站發來的能量有可能被 0 或 1 或 2 個其他發射站所接受,特別是為了安 全,每個發射站接收到的能量總和是我們很關心的問題。由於資料很多,現只需要你幫忙計 算出接收最多能量的發射站接收的能量是多少。

輸入格式

第 1 行:乙個整數 n;

第 2 到 n+1 行:第 i+1 行有兩個整數 hi 和 vi,表示第 i 個人發射站的高度和發射的能量值。

輸出格式

輸出僅一行,表示接收最多能量的發射站接收到的能量值,答案不超過 longint。

輸入輸出樣例

輸入 #1複製

34 2

3 56 10

輸出 #1複製

7說明/提示

對於 40%的資料,1<=n<=5000;1<=hi<=100000;1<=vi<=10000;

對於 70%的資料,1<=n<=100000;1<=hi<=2,000,000,000;1<=vi<=10000;

對於 100%的資料,1<=n<=1000000;1<=hi<=2,000,000,000;1<=vi<=10000。

思路:

兩種做法。

1.維護兩個單調遞減棧,尋找每個發射站右邊(左邊)第乙個比他大的站台,然後把能量加給他,取最大能量的站台

2.維護乙個單調遞減棧,每個發射站左邊的能量來自於左邊小於他的單調遞減序列(在插入這個發射站時候算出),右邊能量來自於每次往這個發射站右邊插入乙個比其能量小的站。

acnew

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int inf =

0x3f3f3f3f

;const

int maxn =

1e6+7;

int h[maxn]

,v[maxn]

;ll ans[maxn]

;struct node stk[maxn]

;int

main()

int top =0;

for(

int i =

1;i <= n;i++

) ans[stk[top]

.id]

+= v[i]

;//每個數左邊貢獻

stk[

++top]=;

} ll res =0;

for(

int i =

1;i <= n;i++

)printf

("%lld\n"

,res)

;return0;

}

ac1

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const ll inf =

0x3f3f3f3f3f3f3f3f

;struct que

stk[

1000006

],a[

1000006];

intmain()

ll top =

0,ans =0;

a[n +1]

.h = inf;

for(

int i =

1;i <= n +

1;i++

)//遞減單調棧

if(top)stk[top]

.l +

= a[i]

.v; stk[

++top]

.h = a[i]

.h;stk[top]

.v = a[i]

.v;stk[top]

.l = len;

}printf

("%lld\n"

,ans)

;return0;

}

ac2

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const ll inf =

0x3f3f3f3f3f3f3f3f

;struct que

stk[

1000005

],a[

1000005];

ll num[

1000005];

intmain()

ll top =

0,ans =0;

for(

int i =

1;i <= n;i++

)//遞減單調棧

num[stk[top]

.i]+

= a[i]

.v; stk[

++top]

.h = a[i]

.h;stk[top]

.v = a[i]

.v;stk[top]

.i = i;

}

top =0;

for(

int i = n;i >=

1;i--

) num[stk[top]

.i]+

= a[i]

.v; stk[

++top]

.h = a[i]

.h;stk[top]

.v = a[i]

.v;stk[top]

.i = i;

}for

(int i =

1;i <= n;i++

)ans =

max(ans,num[i]);

printf

("%lld\n"

,ans)

;return0;

}

單調棧 洛谷 P1901 發射站

某地有 n 個能量發射站排成一行,每個發射站 i 都有不相同的高度 hi,並能向兩邊 當 然兩端的只能向一邊 同時發射能量值為 vi 的能量,並且發出的能量只被兩邊最近的且比 它高的發射站接收。顯然,每個發射站發來的能量有可能被 0 或 1 或 2 個其他發射站所接受,特別是為了安 全,每個發射站接...

P1901 發射站 單調棧

題目描述 某地有 n 個能量發射站排成一行,每個發射站 i 都有不相同的高度 hi,並能向兩邊 當 然兩端的只能向一邊 同時發射能量值為 vi 的能量,並且發出的能量只被兩邊最近的且比 它高的發射站接收。顯然,每個發射站發來的能量有可能被 0 或 1 或 2 個其他發射站所接受,特別是為了安 全,每...

P1901 發射站(單調棧)

假設當前有 a 1 7 a 2 5 a 3 4 三個發射塔,現在在後面加乙個發射塔,高度為 a 4 6a 4 要接受 a 3 a 2 這兩個發射塔的訊號,以及將自身的訊號發射給 a 1 很明顯利用單調棧,將 a 3 出棧,再將 a 2 出棧,最後棧內只剩下 a 1 a 4 最後統計每乙個位置處的能量...