题意:这题是要找最大的矩形面积。
解题思路:这题的关键是要找每个条形能够往左和往右能够到达的最大长度。我最开始的思路是单调栈去维护,只要入栈的元素比栈顶元素小,栈顶就要出栈,并且知道其最右能够到达的最远距离。当要入栈的元素已经找到了位置,那么它左边的元素所在的位置就是其能到达的最左距离。
这道题比较坑,要用__int64位,而且在当栈为空时,加入的新元素的最左是能够到达1的,这里我开始没发现,结果WA到死。。。
这里还有一个dp版本的,感觉实际上和单调栈差不多,都是找最左和最右的距离。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100005; struct Node { __int64 h; int id; }Stack[maxn]; struct Keep { __int64 l,r,h; }res[maxn]; __int64 n,top,hi[maxn]; int main() { while(scanf("%I64d",&n)!=EOF && n) { for(__int64 i = 1; i <= n; i++) { scanf("%I64d",&hi[i]); res[i].l = res[i].r = i; res[i].h = hi[i]; } top = 0; for(__int64 i = 1; i <= n; i++) { while(top > 0 && hi[i] <= Stack[top-1].h) { res[Stack[top-1].id].r = i - 1; top--; } Stack[top].id = i; Stack[top].h = hi[i]; if(top != 0) res[i].l = Stack[top-1].id + 1; else res[i].l = 1; //最容易丢掉的条件,一直WA的原因 top++; } while(top > 0) { res[Stack[top-1].id].r = n; top--; } __int64 ans = 0; for(int i = 1; i <= n; i++) { __int64 area = (res[i].r - res[i].l + 1) * res[i].h; if(area > ans) ans = area; } printf("%I64d\n",ans); } return 0; }
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 100005; int n,l[maxn],r[maxn]; __int64 hi[maxn]; int main() { while(scanf("%d",&n)!=EOF && n) { for(int i = 1; i <= n; i++) scanf("%I64d",&hi[i]); l[1] = 1; r[n] = n; int t; for(int i = 2; i <= n; i++) //更新每个l[i] { t = i; while(t > 1 && hi[t-1] >= hi[i]) t = l[t-1]; l[i] = t; } for(int i = n - 1; i >= 1; i--) //更新每个r[i] { t = i; while(t < n && hi[t+1] >= hi[i]) t = r[t+1]; r[i] = t; } __int64 ans = 0, tmp = 0; for(int i = 1; i <= n; i++) { tmp = (r[i] - l[i] + 1) * hi[i]; if(tmp > ans) ans = tmp; } printf("%I64d\n",ans); } return 0; }