首页 > 其他分享 >POJ-2559-Largest Rectangle in a Histogram-DP或者单调栈

POJ-2559-Largest Rectangle in a Histogram-DP或者单调栈

时间:2023-03-25 13:37:22浏览次数:35  
标签:矩形 int 2559 top long Histogram POJ ans include


Problem E

 

Largest Rectangle in a Histogram

 

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2498    Accepted Submission(s): 778

 

 

Problem Description

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:

HDU <wbr>1506 <wbr>Largest <wbr>Rectangle <wbr>in <wbr>a <wbr>Histogram

 

Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.

 

 

Input

The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1 <= n <= 100000. Then follow n integers h1, ..., hn, where 0 <= hi <= 1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.

 

 

Output

For each test case output on a single line the area of the largest rectangle in the specified histogram. Remember that this rectangle must be aligned at the common base line.

 

 

Sample Input


 


7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0

 

 

Sample Output


 


8 4000

 

算法分析:

一个矩形只要求出高和宽就行,高即输出,我们要求就是宽,我们以一个矩形为扩展它能达到的最大宽度(由它的高所限定,两边和它能拼凑起矩形必须为连续且小于它的)

设l[i]为左边连续的不小于第i个矩形的矩形坐标点

设r[i]为右边连续的不小于第i个矩形的矩形坐标点

接下来便枚举每个矩形的高度

面积= r[i]-l[i]+1)*a[i]

单调栈栈的目的也是求l[i]和r[i],很简单看看代码就能理解。

 

代码实现:

 

#include<bits/stdc++.h>
using namespace std;
long long f,r[100001],l[100001],a[100001];
int main()
{
  while(1)
   {
       memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));

       long long n,i,j,maxx=-99999999999;
       cin>>n;
       if(n==0)  break;
       for(i=1;i<=n;i++)
           {
               cin>>a[i];
               l[i]=i;
               r[i]=i;
           }
       //两个for循环为求改点最大宽度
        for(i=2;i<=n;i++)         
        {
            j=i;
            while(j>=1&&a[i]<=a[j])  j=l[j]-1;//通过之前的l[i]结果更快地找到区间,若是直接用j--;会超时
            l[i]=j+1;                         //如果满足while就直接-1,不能确定下一个是否满足,(如果都满足,j是>=1的

        }
         for(i=n-1;i>=1;i--)
         {
             j=i;
             while(j<=n&&a[i]<=a[j])  j=r[j]+1;
             r[i]=j-1;
         }
         for(i=1;i<=n;i++)
         {
             f=(r[i]-l[i]+1)*a[i];
             maxx=max(f,maxx);
         }
         cout<<maxx<<endl;
   }
  return 0;
}

单调栈

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <vector>
using namespace std;
typedef long long ll; 
const int N=100005;
ll h[N];
ll l[N],r[N];
int main(){
    
	int n;
	while(scanf("%d",&n)!=-1)
	{
		if(n==0) break;
		stack<ll>s;
	    for(int i=1;i<=n;i++)
	    	scanf("%lld",&h[i]);
		h[n+1]=0; ///注意这里
		for(int i=1;i<=n+1;i++)
		{
			//cout<<i<<endl;
			while(!s.empty()&&h[s.top()]>h[i])
			{
				r[s.top()]=i;
				s.pop();
			}
			if(s.size()==0)
				l[i]=0;
			else
			    l[i]=s.top();
			s.push(i);
		}
		ll ans = 0;
        for(int i=1;i<=n;i++)
            ans = max(ans,(r[i]-l[i]-1)*h[i]);
        printf("%lld\n", ans);
	}
     return 0;
 }

另一种思想的单调栈

#include<cstdio>
#include<stack>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> PII;
const int MX = 100000 + 5;

int main()
{
    int N;
    int height;
    while(~scanf("%d",&N) &&N)
    {
        stack<PII>Q;
        LL ans = 0;
        for(int i=0;i<N;i++)
        {
            scanf("%d",&height);
            LL width = 0;
            while(!Q.empty() && Q.top().first>=height ){ //当栈顶元素大于当前元素
                LL tmpH = Q.top().first;
                LL tmpW = Q.top().second;
                Q.pop();width+=tmpW;//每次出栈的时候,就是计算以这个矩形的高度为最长高度的最大面积,
                //因为左边的比他小,所以只需要向右延伸就可以了
                //所以每次出栈的时候,就是出栈后的栈顶元素宽度+1
                ans = max(ans,tmpH*width);//如果大于当前的最大面积就更新
            }
            Q.push(make_pair((LL)height,(LL)width+1));
        }
        int tmp = 0;
        while(!Q.empty()){
            ans = max(ans,Q.top().first*(tmp+Q.top().second));//原理和上面一样
            tmp+=Q.top().second;Q.pop();
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

标签:矩形,int,2559,top,long,Histogram,POJ,ans,include
From: https://blog.51cto.com/u_14932227/6149350

相关文章

  • POJ - 3321 Apple Tree
    原题链接思路答案不好直接维护,所以,我们可以采用DFS序来解决这一问题。设\(l_u\)是以\(u\)为根的子树中最小的时间戳,\(r_u\)是以\(u\)为根的子树中最大的时间戳......
  • Can not set java.lang.String field com.jsedc.log.pojo.entity.voSyslogV0.happenT
    未加泛型约束的result,其List中的实体对象会被序列化为LinkedHashMap,实际结构为Result<List<LinkedHashMap<String,String>>>导出excel时对象赋值失败......
  • [POJ] 2251地牢大师
    来源:《信息学奥赛一本通》,POJ2251算法标签BFS题目描述你现在被困在一个三维地牢中,需要找到最快脱离的出路!地牢由若干个单位立方体组成,其中部分不含岩石障碍可以直接通......
  • 解决:无法获取实体类com.xxx.pojo.AppUser对应的表名
    问题:在Application启动类中使用的@MapperScan注解,导入的包为:org.mybaties.spring.annotation.MapperScan解决:导入包改为:tk.mybatis.spring.annotation.MapperScan,解......
  • Apple Catching POJ - 2385
     有个人在2柯树之间来回,在1~T的时刻i时,其中一颗棵树会掉一个果子,规定只能掉头m次,问最多能获得多少果子  f[i][j]#include<iostream>#include<algorithm>......
  • Polygon POJ - 1179
       除了维护一个区间最大值,还要一个最小值,(有负数)  #include<iostream>#include<algorithm>#include<cstring>usingnamespacestd;constintN=160......
  • Communication System POJ - 1018
    目前有一个公司需要购进宽带设备,每种设备有多款机器供选择,每种设备都需购进一台,现给出每台设备的带宽p与价格q,要求选择设备的最小带宽min(p)/add(q)(其中min(p)表示所有购......
  • STL:map映照容器的简单用法(poj 2503 Babelfish)
    STL中map映照容器由一个键值和一个映照数据组成,具有一一对应的关系。结构为:键值--映照数据       例: aaa --111             bbb--222   ......
  • poj-1704 nim变形
    #include<stdio.h>#include<iostream>#include<math.h>#include<stdlib.h>#include<ctype.h>#include<algorithm>#include<vector>#include<string.h>#include<q......
  • poj-2348
    #include<stdio.h>#include<iostream>#include<math.h>#include<stdlib.h>#include<ctype.h>#include<algorithm>#include<vector>#include<string.h>#include<q......