首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

POJ 2796 Feel Good:單調棧求區間最小值×區間和最大值

     編輯:關於C++

題目大意

給定 n (≤100,000) 個非負整數 a[i]。定義區間 [l, r] 的價值 = (∑_{i=l}^r a[i]) × min_{i=l}^r a[i]。求最大價值及對應區間端點(任意一個)。

單調棧思路

維護單調遞增棧,棧中元素為數組下標,對應值嚴格遞增。對每個位置 i 作為「最小值」的貢獻:它能向左右擴展到第一個比它小的位置。即 L[i] = 左側第一個 a[j] < a[i] 的位置,R[i] = 右側第一個 a[j] < a[i] 的位置。則以 i 為最小值的最大區間為 (L[i]+1, R[i]-1)。
區間和可用前綴和 O(1) 查詢。遍歷所有 i 計算價值,取最大。

棧中存儲結構

為了 O(1) 獲取區間和與最小值,棧節點存儲:
sum:該區間元素和,minVal:最小值(即棧底元素值),left:區間最左下標,cnt:區間長度。
新元素入棧時,彈出所有 ≥ 它的節點,合併其區間信息(累加 sum、cnt,更新 left),然後將新元素作為新區間最小值入棧。
遍歷結束後,再將棧中剩餘節點依次彈出計算價值(同樣合併到下一節點)。

C++ 實現

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved