洛谷P1901 發射站

鏈接:P1901

題目描述
某地有 N 個能量發射站排成一行,每個發射站 i 都有不相同的高度 Hi,並能向兩邊(當 然兩端的只能向一邊)同時發射能量值爲 Vi 的能量,並且發出的能量只被兩邊最近的且比 它高的發射站接收。

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

輸入格式
第 1 行:一個整數 N;

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

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

輸入輸出樣例
輸入 #1
3
4 2
3 5
6 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.新的元素加進來以後,會對他在棧中下面那個元素傳輸能量,也就是離他最近還高於他的那個。P.S.(不需要對棧空時進行特判,我們只是對0這個元素傳輸了能量而已,最後不統計就行了)
那麼確定思路以後,我們算法流程就是
for{
讀入新元素
while(棧非空&&新元素高度大於棧頂元素高度)新元素能量加上棧頂元素能量,退棧; 棧頂元素能量加上新元素能量(對應第二種情況)
將新元素加入棧中
}
掃一遍傳輸能量的數組,找到max輸出即可。

代碼:

#include <cstdio>
#include <iostream> 
#include <cstring>
using namespace std;
int n,h[1000001],w[1000001],top,stack[1000001],k[1000001],maxx,ans[1000001];
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d%d",&h[i],&w[i]);
     for (int i=1;i<=n;i++)
        {
        	while (h[i]>h[stack[top]] && top>=1)
        	{
        		k[stack[top]]=i;
        		top--;
			}
			stack[++top]=i;
		}  //正着掃一遍
		top=0;
		for (int i=1;i<=n;i++)
		{
			ans[k[i]]+=w[i];
		}
		memset(k,0,sizeof(k));
for (int i=n;i>=1;i--)
        {
        	while (h[i]>h[stack[top]] && top>=1)
        	{
        		k[stack[top]]=i;
        		top--;
			}
			stack[++top]=i;
		}  //反着掃一遍
		for (int i=1;i<=n;i++)
		{
			ans[k[i]]+=w[i];
		}
		for (int i=1;i<=n;i++)
		{
			maxx=max(ans[i],maxx);
		}
		printf("%d",maxx);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章