今天是2019.6.4 距离NOIP2019还有157天
这是一道单调栈的好题
记得高一下暑假集训的时候肖宇朔学长讲过
今天突然想到了这道题拿出来再做一遍
应该是2019年第一道正常难度的题
题解原先在洛谷上发过一遍了
这里再发一遍
题解:只需从左到右维护一个高度递增的栈并且记录每个元素的宽度
每弹出一个元素的时候用它更新答案
为什么呢
因为所有可能成为答案的矩形它的四条边都无法再向四周扩散
每一个给定的矩形宽度都为一,所以我们不妨从左到右遍历一遍整个矩形图
假设第一个矩形高是5,那么包含它的可能成为答案的矩形的高度一定是5(显然)
那么第一个矩形的右面有多少个连续不断的高于第一个矩形矩形就决定了包含它的可能答案(tot)
如果遇到小于5的一个矩形,就弹出栈中元素,由此合并出可能的答案
最后枚举答案求出最大值即可
上代码
#include<cstdio> #include<cstring> #include<cmath> #include<cctype> #include<cstdlib> #include<string> #include<iostream> #include<algorithm> #include<set> #include<map> #include<queue> #include<stack> #include<vector> #define enter puts("") #define space putchar(' ') using namespace std; typedef long long ll; ll read() { ll op = 1, ans = 0; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = 0; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return op ? ans : -ans; } void write(ll x) { if(x < 0) { x = -x; putchar('-'); } if(x >= 10) write(x / 10); putchar(x % 10 + '0'); } const int N = 100005; struct Drug { int height; int count; }; Drug st[N]; ll top, h, n, ans, tot, tmp;//tmp存宽度,tot存可能的矩形面积 int main() { while(scanf("%d", &n) != EOF && n) { top = 0; ans = 0; for(int i = 1; i <= n; i++) { h = read(); tmp = 0; while(top > 0 && st[top - 1].height >= h)//维护单调栈 { tot = st[top - 1].height * (st[top - 1].count + tmp); if (tot > ans) ans = tot; tmp += st[top - 1].count; --top; } st[top].height = h; st[top].count = 1 + tmp; ++top; } tmp = 0; while(top > 0)//出栈 { tot = st[top - 1].height * (st[top - 1].count + tmp); ans = max(tot, ans); tmp += st[top - 1].count; --top; } write(ans); enter; } return 0; }