ACM解題技巧---(單調棧)+ 題目總結

單調是一種思想,當我們解決問題的時候發現有許多冗雜無用的狀態時,我們可以採用單調思想,用單調棧或類似於單調隊列的方法去除冗雜狀態,保存我們想要的狀態

第一題

題目傳送門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;
} 

第二題:

持續更新中…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章