zoukankan      html  css  js  c++  java
  • 题解 POJ 2559-SP1805 【HISTOGRA

    • 题目链接: https://www.luogu.org/problemnew/show/SP1805
      http://poj.org/problem?id=2559

    • 思路:

      单调栈

      首先如果所有矩形的高度是单调递增的,即新加入的矩形比上一个高,那么把加进来直至加完,这是我们就把分别每个矩形的高度看做是最大子矩形的高度,分别向左右拓展求得最大面积。

      然而矩形的高度不一定是递增的,如果新加入的矩形比上一个小,那么之前这些矩形的高度对于后面的计算就没用了。我们就在这时候把比这个新加的矩形高的部分全部删掉,这样就能保持矩形都是单调递增的。

      具体实现的方法简单说就是将之前比这高的矩形弹出栈知道遇到比新矩形低的矩形,同时累计他们的宽度之和,乘以这个更矮矩形的高度来更新答案。最后再按这个方法把所有矩形弹出去来更新答案。

    • 小技巧:

      • 将a[n+1]设为0保证最后能将所有矩形弹出去(想想为什么)
    • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cstring>
    #include <cctype>
    #define ll long long  
    using namespace std;
    const int maxn=100010;
    int a[maxn],w[maxn],s[maxn];//w记录宽度
    ll ans;
    int n;
    template <class T>inline void read(T &x){
    	x=0;char c;int neg=0;
    	while(!isdigit(c=getchar()))neg=c=='-';
    	x=c-48;
    	while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    	x=neg?-x:x;
    	return ;
    }  
    inline void solve(){
    	int p;
    	a[n+1]=p=0;//这样最后能将所有矩形弹出栈
    	for(register int i=1;i<=n+1;i++){
    		if(a[i]>s[p]){
    			s[++p]=a[i];
    			w[p]=1;
    		}
    		else {
    			int wid=0;
    			while(s[p]>a[i]){
    				wid+=w[p];
    				ans=max(ans,(ll)wid*s[p]);
    				p--;
    			}
    			s[++p]=a[i],w[p]=wid+1;
    		}
    	}
    	cout<<ans<<endl;
    	return;
    }
    int main()
    {
    	while(scanf("%d",&n)!=EOF){
    	    if(!n)break;
    		ans=0;
    		for(register int i=1;i<=n;i++){
    		  read(a[i]);
    		}
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    JS精度问题(0.1+0.2 = 0.3吗?)
    力导向算法的研究与改进
    React Hooks的memo和useCallback
    React Hooks vs Vue Composition Api
    docker常用命令
    win10一台电脑上配置多个git账户
    eslint+prettier 统一代码风格
    c#中关于值类型,引用类型在栈,堆栈的分配
    js里的__proto__和prototype
    golang之冒泡排序
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8687181.html
Copyright © 2011-2022 走看看