Histogram LightOJ
来源:互联网 发布:视频编辑软件排行 编辑:程序博客网 时间:2024/06/08 01:25
题面
题意
有一串由矩形组成的图,先要求出这幅图中所能容纳的最大矩形的面积
总体思路
求出以各个小矩形高度为宽所能达到的最大面积,此时我们称这个最大矩形被这个小矩形统治,我们只需求出每一个小矩形统治的最大矩形的左端点和右端点.
法1(单调栈)
方法解释
让矩形依次入栈,当入栈矩形小于栈顶时,说明此时的栈顶不能统治该矩形,其右端点即为入栈矩形的位置-1.最后将让元素全部出栈,它们的右端点均为这个图的右端点
当矩形入栈后,其下面的矩形必然小于等于它,若小于,则其左端点为它下面那个矩形的位置+1,若等于,则其左端点为其下面矩形的左端点.第一个元素的左端点为整个图的左端点.
代码
#include<bits/stdc++.h>#define P pair<int,int>#define N 100100using namespace std;int n,T,TT;int get(vector <int> a){ int i,k,le[N],ri[N],mx=0; P tmp; stack<P> st; le[0]=0; a.push_back(0); tmp.first=tmp.second=0; st.push(tmp); for(i=1;i<=n+1;i++) { k=st.top().first; while(a[i]<k&&!st.empty()) { ri[st.top().second]=i-1; st.pop(); k=st.top().first; } if(a[i]==k) le[i]=le[st.top().second]; else le[i]=st.top().second+1; tmp.first=a[i]; tmp.second=i; st.push(tmp); } for(i=1;i<=n;i++) { mx=max(a[i]*(ri[i]-le[i]+1),mx); } return mx;}int main(){ int i,j,p,mx=0; vector<int> a; cin>>T; TT=T; while(T--) { a.clear(); scanf("%d",&n);// cout<<n; a.push_back(0); for(i=1;i<=n;i++) { scanf("%d",&p); a.push_back(p); }// get(a); printf("Case %d: %d\n",TT-T,get(a)); }}
法2
方法解释
求左端点:从小到大枚举,若每个矩形左端点的初始值为自身,若它小于等于它左端点减一的矩形的左端点,则将其左端点更新为那个矩形的左端点,如此循环更新直到大于那个矩形或为一时停止,每一个点都这样操作一遍即可.
求右端点:从大到小枚举,与左端点相同此方法每一次操作都将两块连起来,类似并查集,故复杂度为O(n).
代码
#include<bits/stdc++.h>#define N 100010using namespace std;int a[N],n,le[N],ri[N],mx,T,TT;int main(){ int i,j; cin>>T; TT=T; while(T--) { mx=0; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&a[i]); le[i]=i; while(le[i]>1&&a[i]<=a[le[i]-1]) { le[i]=le[le[i]-1]; } } for(i=n;i>=1;i--) { ri[i]=i; while(ri[i]<n&&a[i]<=a[ri[i]+1]) { ri[i]=ri[ri[i]+1]; } } for(i=1;i<=n;i++) { mx=max(a[i]*(ri[i]-le[i]+1),mx); } printf("Case %d: %d\n",TT-T,mx); }}
法3
方法解释
首先用n*log(n)处理出以一个点为左端点,2^i为长度的一段数最小值,处理和查找时记得记录位置。
处理方法为:长度为2^i的最小值为两个长度为2^(i-1)的较小值,以此递推下去。
查找方法:见下图:
两个红色部分的最小值即为这一段的最小值
预处理之后,每次找到最小值的位置,以此计算它统治的矩形来更新答案,并以它为中心分成两段,分别继续查找。因为每个点都被查了一次,故复杂度为O(n).
代码
#include<bits/stdc++.h>#define N 50010#define P pair<int,int>using namespace std;int num[N],n,dp[N][100],k[N][100],T,TT,l,r,ans;int log(int u){ int res=0; while(u) { res++; u>>=1; } return res;}int ask(int u,int v){ int len; len=v-u+1; len=log(len)-1; if(dp[u][len]<dp[v-(1 << len)+1][len]) { return k[u][len]; } else { return k[v-(1 <<len)+1][len]; }}void find(int u,int r){ if(u>r) return; int i,tmp; tmp=ask(u,r); ans=max(ans,num[tmp]*(r-u+1)); find(u,tmp-1); find(tmp+1,r);}int main(){ cin>>T; TT=T; while(T--) { int i,j; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&num[i]); dp[i][0]=num[i]; k[i][0]=i; } for(i=1;(1 << i)<=n;i++) { for(j=1;j+(1 << i)-1<=n;j++) { if(dp[j][i-1]<dp[j+(1 << (i-1))][i-1]) { dp[j][i]=dp[j][i-1]; k[j][i]=k[j][i-1]; } else { dp[j][i]=dp[j+(1 << (i-1))][i-1]; k[j][i]=k[j+(1 << (i-1))][i-1]; } } } ans=0; find(1,n); printf("Case %d: %d\n",TT-T,ans); }}
法4
方法解释
首先建一棵笛卡尔树,利用其性质进行分制,复杂度为O(n)。
代码
#include<bits/stdc++.h>#define N 50010using namespace std;struct Tree{ int lef,rig;}tree[N];int T,TT,num[N],fa[N],ans,n;void find(int now,int l,int r){ if(now==-1) return; ans=max(num[now]*(r-l+1),ans); find(tree[now].lef,l,now-1); find(tree[now].rig,now+1,r);}int main(){ int i,j,now,k,gen; cin>>T; TT=T; while(T--) { scanf("%d",&n); for(i=1;i<=n;i++) { tree[i].lef=tree[i].rig=-1; scanf("%d",&num[i]); } now=1; gen=1; fa[1]=-1; for(i=2;i<=n;i++) { k=now; while(num[i]<num[k]&&k!=-1) { k=fa[k]; } if(k==-1) { tree[i].lef=gen; fa[gen]=i; fa[i]=-1; now=gen=i; } else { tree[i].lef=tree[k].rig; tree[k].rig=i; now=i; fa[i]=k; } } ans=0; find(gen,1,n); printf("Case %d: %d\n",TT-T,ans); }}
阅读全文
1 0
- Histogram LightOJ
- LightOJ 1083 Histogram
- 一道题--4遍A!:Histogram(LightOJ 1083)
- POJ 2559 / HDU 1506 / LightOJ 1083 Largest Rectangle in a Histogram (单调栈)
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- [LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- LightOJ
- linux c 一站式学习 extern关键词作用、变量的声明与定义以及extern与include的区别(都与extern有关)
- Android 8.0 源码下载方式
- Unix-Linux编程实践教程——第五章
- libaio.so.1()(64bit) is needed by MySQL-server-5.5.25a-1.rhel5.x86_64
- Hive安装
- Histogram LightOJ
- CVPixelBuffer的创建数据填充以及数据读取
- 喜大普奔 我与SpringMVC的纠纠缠缠第一解
- C语言结构体的强制类型转换
- Io 异常: The Network Adapter could not establish the connection 解决方法
- STM32单片机电源端并联电容的重要性
- Java面试题集(71-85)
- opencv + vs 2015开发环境配置
- web.xml配置详解