【資料結構】單調棧
阿新 • • 發佈:2019-02-03
- 基本介紹
- 模板題目
- 程式碼實現
基本介紹
之前沒有寫過棧 棧是隻能在某一端插入和刪除的特殊線性表 就像一個桶一樣 我們可以用STL 也可以自己寫
進棧 top++ 然後 _stack[top]=進棧元素
退棧 可以將退棧後的一個元素賦值到一個地方 top–
單調棧 故名思議 就是多了個 單調 的要求
(以下文字引用於Shuyu Fang的部落格)
若是單調遞增棧 則從棧頂到棧底的元素是嚴格遞增的 若是單調遞減棧 則從棧頂到棧底的元素是嚴格遞減的 越靠近棧頂的元素越後進棧
元素進棧過程: 對於單調遞增棧 若當前進棧元素為e 從棧頂開始遍歷元素 把小於e或者等於e的元素彈出棧 直接遇到一個大於e的元素或者棧為空為止 然後再把e壓入棧中 對於單調遞減棧 則每次彈出的是大於e或者等於e的元素
模板題目
洛谷p1901 發射站
題目描述
某地有 N 個能量發射站排成一行,每個發射站 i 都有不相同的高度 Hi,並能向兩邊(當 然兩端的只能向一邊)同時發射能量值為 Vi 的能量,並且發出的能量只被兩邊最近的且比 它高的發射站接收。
顯然,每個發射站發來的能量有可能被 0 或 1 或 2 個其他發射站所接受,特別是為了安 全,每個發射站接收到的能量總和是我們很關心的問題。由於資料很多,現只需要你幫忙計 算出接收最多能量的發射站接收的能量是多少。
輸入輸出格式
輸入格式:
第 1 行:一個整數 N;
第 2 到 N+1 行:第 i+1 行有兩個整數 Hi 和 Vi,表示第 i 個人發射站的高度和發射的能量值。
輸出格式:
輸出僅一行,表示接收最多能量的發射站接收到的能量值,答案不超過 longint。
輸入輸出樣例
輸入樣例:
3
4 2
3 5
6 10
輸出樣例:
7
題解中有講解
程式碼實現
3
4 2
3 5
6 10
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
#define ll long long
#define in =read()
const int size = 1000000 + 50;
ll _stack[size],pos[size],b[size];
ll n,top,ans;
struct data{
ll h,v;
}a[size];
inline ll max(ll x,ll y)
{
return x>y?x:y;
}
inline ll read()
{
ll num=0,f=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-1; ch=getchar();
}
while(isdigit(ch)){
num=num*10+ch-'0'; ch=getchar();
}
return num*f;
}
inline void f (int x)
{
while(top&&_stack[top]<=a[x].h) top--;
b[pos[top]]+=a[x].v; _stack[++top]=a[x].h; pos[top]=x;
cout<<b[top]<<" "<<_stack[top]<<" "<<pos[top]<<endl;
}
int main()
{
int i;
n in;
for(i=1;i<=n;i++){
a[i].h in; a[i].v in;
}
for(i=1,top=0;i<=n;i++) f(i);
for(i=n,top=0;i;i--) f(i);
/* for(int i=0;i<=n;i++) {
cout<<b[i]<<" "<<_stack[i]<<" "<<pos[i];
cout<<endl;
}*/
for(i=1;i<=n;i++) ans=max(ans,b[i]);
printf("%d",ans);
}
//COYG