單調是一種思想,當我們解決問題的時候發現有許多冗雜無用的狀態時,我們可以採用單調思想,用單調棧或類似於單調隊列的方法去除冗雜狀態,保存我們想要的狀態
第一題
題目傳送門Hdu 1506 poj2559 最大矩形面積
思路:棧裏面去維護一個長方形的高,保持這個單調遞增,遇到遞減,就出棧然後更新。。。
AC代碼
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include <list>
#include<bitset>
#include<cmath>
#include<set>
#include<vector>
#include<stack>
#include<list>
#include<deque>
#include<map>
//#include <unordered_map>
//#include <unordered_set>
#include<queue>
#include <functional>
#include <climits>
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define inf_add 0x3f3f3f3f
#define MOD 100000
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
#define rep(i, x, y) for(register int i = x; i <= y; ++i)
#define repd(i, x, y) for(register int i = x; i >= y; --i)
#define file(s) freopen(s".in", "r", stdin), freopen(s".my", "w", stdout)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair <ll, int> pli;
typedef pair <int, ll> pil;
typedef pair <ll, ll> pll;
const double eps = 1e-6;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template<class T>void read(T &x){
x=0;ll f=0;char ch=getchar();
while(ch<'0'||ch>'9') {f|=(ch=='-');ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return;
}
// hdu 1506
// 求矩形的面積 + 單調棧
// 記得開ll 還有n == 0 特判斷結束,不然WA
const int maxn = 1e5+10;
struct node{
ll w; // 寬度
ll h; //高度
}sa[maxn];
ll n, ans_area, cur_area, tot_w;
stack<node>st;
void input(){
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
rep(i,1,n) read(sa[i].h),sa[i].w = 1;
while(!st.empty())
st.pop();
ans_area = 0;
st.push(sa[1]);
rep(i,2,n){
//維護單調棧的性質
if(sa[i].h>=sa[i-1].h){
st.push(sa[i]);
}else{
tot_w = 0,cur_area = 0;
while(!st.empty()&&st.top().h>sa[i].h){
tot_w += st.top().w;
// 總寬度乘以當前矩形高度
cur_area = tot_w * st.top().h;
chkmax(ans_area,cur_area);
st.pop();
}
sa[i].w +=tot_w;
st.push(sa[i]);
}
}
//最後就是把單調棧的值更新就行
tot_w = 0;
cur_area = 0;
while(!st.empty()){
tot_w += st.top().w;
cur_area = tot_w * st.top().h;
chkmax(ans_area,cur_area);
st.pop();
}
printf("%lld\n",ans_area);
}
}
void solve(){
}
int main(){
//ios::sync_with_stdio(false);
//cin.tie(0);
#ifdef LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#if __cplusplus >= 201103L
auto start = steady_clock::now();
#endif
#endif
input();
// solve();
return 0;
}