题意:
给定n个长方形,这n个长方形的底边都在一条直线上,然后输入n个长方形的高,问在这组图像中最大长方形的面积。
解题思路:
因为每个长方形的底边长都是1,所以可以用数组的下标表示每一个长方形,我们所需做的就是求出此长方形能向左向右延伸的最大长度LEN,然后LEN*H即为面积。因为输入的长方形多达一亿个,所以不能一个个从头到尾判断。
L[i]代表第i个长方形向左延伸的最大下标,R[i]表示第i个长方形向右延伸的最大下标。
LEN = R[i] - L[i]+1.
状态转移方程:
if(h[i-1] >= h[i]) L[i] = L[i-1];
if(h[i+1] >= h[i]) R[i] = R[i-1];
#include <set>
#include <numeric>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <string>
#include <sstream>
#include <map>
#include <functional>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
#define REP(idx1,num1) for(int idx1=0;idx1<(num1);idx1++)
#define pb push_back
#define empb emplace_back
#define mp make_pair
#define mem(s) memset(s,0,sizeof(s));
const double EPS = 1e-6;
const int maxn = 100000+10;
//ULL d[maxn];
ULL a[maxn];
ULL l[maxn];
ULL r[maxn];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin >> n && n)
{
// d[0] = 0;
//dp
for(int i = 1; i <= n; ++i)
{
cin >> a[i];
l[i] = i;r[i] = i;//初始化
}
for(int i = 1; i <= n; ++i)
{
ULL t = i;
while(t > 1 && a[i] <= a[t-1])
t = l[t-1];
l[i] = t;
}
for(int i = n; i >= 1; --i)
{
ULL t = i;
while(t < n && a[i] <= a[t+1])
t = r[t+1];
r[i] = t;
}
//dp
ULL max_d = 0;
for(int i = 1; i <= n; ++i)
{
max_d = max(max_d,a[i]*(r[i] - l[i] + 1));
}
cout << max_d << endl;
}
return 0;
}
2023



被折叠的 条评论
为什么被折叠?



