A - Largest Rectangle in a Histogram(直方图中最大的矩形)
A - Largest Rectangle in a Histogram
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:
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
Inputcopy
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Output
8
4000
Hint
Huge input, scanf is recommended.
题意
找出直方图中最大的矩形
暴力做法
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
#define X first
#define Y second
typedef pair<int,int> pii;
typedef long long LL;
const char nl = '\n';
const int N = 1e5+10;
const int M = 2e5+10;
int n,m;
int a[N],st[N],tt;
LL ans;
void solve(){
while(1){
ans = 0;
tt = 0;
cin >> n;
if(n == 0)break;
for(int i = 1; i <= n; i ++)cin >> a[i];
for(int i = 1; i <= n; i ++){
int l = i;
while(l && a[l - 1] >= a[i])l --;
int r = i;
while(r < n && a[r + 1] >= a[i])r ++;
ans = max(ans,(LL)a[i] * (r - l + 1));
}
cout << ans << nl;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
solve();
}
优化
暴力做法的思路是枚举每一个矩形,找到左边最后一个大于等于这个矩形高度的矩形标记下标为
那么答案为
转化->
左边最后一个大于等于这个矩形高度的矩形下标
右边最后一个大于等于这个矩形高度的矩形下标
因此我们可以联想到单调栈(复杂度
代码
点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
#define X first
#define Y second
typedef pair<int,int> pii;
typedef long long LL;
const char nl = '\n';
const int N = 1e5+10;
const int M = 2e5+10;
int n,m;
int h[N],st[N],tt,l[N],r[N];
LL ans;
void init(){
ans = 0;
tt = 0;
}
void solve(){
while(1){
init();
cin >> n;
if(n == 0)break;
for(int i = 1; i <= n; i ++)cin >> h[i];
st[0] = 0;
for(int i = 1; i <= n; i ++){
while(tt && h[i] <= h[st[tt]])tt --;
l[i] = st[tt] + 1;
st[++ tt] = i;
}
tt = 0;
st[0] = n + 1;
for(int i = n; i; i -- ){
while(tt && h[i] <= h[st[tt]])tt --;
r[i] = st[tt] - 1;
st[++ tt] = i;
}
for(int i = 1; i <= n; i ++ ){
ans = max(ans,(LL)h[i] * (r[i] - l[i] + 1));
}
cout << ans << nl;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
solve();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】