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;
    }
    
  • 相关阅读:
    【css】怎么让Chrome支持小于12px 的文字
    java操作linux,调用shell命令
    20个非常有用的Java程序片段
    Java集合详解
    SVN使用指南
    利用SQL语句查询数据库中所有表
    HttpClient-03Http状态管理
    HttpClient-02连接管理
    HttpClient-01基本概念
    IDEA安装插件
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8687181.html
Copyright © 2011-2022 走看看