广告印刷
来源:互联网 发布:广州谷得知乎 编辑:程序博客网 时间:2024/04/29 00:45
Description
最近,afy决定给TOJ印刷广告,广告牌是刷在城市的建筑物上的,城市里有紧靠着的N(N<=400000)个建筑。afy决定在上面找一块尽可能大的矩形放置广告牌。我们假设每个建筑物都有一个高度,从左到右给出每个建筑物的高度H1,H2…HN,0<Hi<=1,000,000并且我们假设每个建筑物的宽度均为1。要求输出广告牌的最大面积。
Input
第一行,一个整数N
第二行,N个空格间隔的整数,表示从左往右每栋楼的高度
Output
一个整数,表示最大面积
Sample Input
65 8 4 4 8 4
Sample Output
24
【分析】
定义两个数组l[maxn],r[maxn]分别表示当前节点可以向左右扩展的最大长度。这个长度的要求是左边(右边)连续的不小于当前节点高度的最大区间长度。
如样例的r便是:r[1]=2;r[2]=1;r[3]=4;r[4]=3;r[5]=1;r[6]=1;现在便是想怎样求得r和l数组。一个最朴素的想法便是枚举每个i然后往右边扫。显然时间复杂度为O(n^2)。不满足数据范围。
可以用单调队列优化。从原序列中依次取出元素插入单调队列。若插入位置为tail,则需满足h[i]>=Q[tail-1]。若不满足,则tail向前移动,继续判断,直到满足为止。很明显,tail向前移动的过程,其实就是元素从队尾出队的过程。注意,在某个元素出队的同时,记下他的r值。用Qr数组记录Q数组中元素下标。那么,r[Qr[tail-1]]=i-Qr[tail-1]。这里i是当前要插入的元素下标,tail-1是要被删除的元素。
最后,答案ans=max{(r[i]+l[i]-1)*h[i]};
【代码】
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<ctime>#include<iostream>#include<algorithm>using namespace std;const int maxn=500005;long long N,v[maxn],Q[maxn],Qr[maxn],t[maxn];long long l[maxn],r[maxn];long long ans=0;void _in(long long &x){char t=getchar();while(t<'0'||'9'<t) t=getchar();for(x=t-'0',t=getchar();'0'<=t&&t<='9';x=x*10+t-'0',t=getchar());}void _init(){_in(N);ans=0;for(int i=1;i<=N;i++) _in(v[i]);}void _solve(){v[0]=-0x7FFFFFFF;v[N+1]=-0x7FFFFFFF;int head=1,tail=2;Q[head]=v[1];Qr[head]=1;for(int i=2;i<=N+1;i++){if(v[i]>=Q[tail-1]){Qr[tail]=i; Q[tail++]=v[i];}else{while(v[i]<Q[tail-1]&&tail!=head){ tail--; r[Qr[tail]]=i-Qr[tail];}Q[tail]=v[i];Qr[tail]=i;tail++;}}memset(Q,0,sizeof(Q));memset(Qr,0,sizeof(Qr));memcpy(t,v,sizeof(v));for(int i=0,j=N+1;i<=N+1;i++,j--) v[i]=t[j];head=1,tail=2;Q[head]=v[1];Qr[head]=1;for(int i=2;i<=N+1;i++){if(v[i]>=Q[tail-1]){Qr[tail]=i; Q[tail++]=v[i];}else{while(v[i]<Q[tail-1]&&tail!=head){ tail--; l[Qr[tail]]=i-Qr[tail];}Q[tail]=v[i];Qr[tail]=i;tail++;}}memcpy(v,t,sizeof(t));memcpy(t,l,sizeof(l));for(int i=0,j=N+1;i<=N+1;i++,j--) l[i]=t[j];for(int i=1;i<=N;i++){long long temp=(r[i]+l[i]-1)*v[i];ans=max(ans,temp);}printf("%I64d\n",ans);}int main(){ _init();_solve();return 0;}
- 广告印刷
- 广告印刷
- 广告印刷
- 广告印刷
- 广告印刷
- 单调队列之广告印刷问题
- 单调队列——广告印刷
- 广告印刷 题解(单调队列)
- NKOJ 2150 【单调队列】广告印刷
- NKOJ 2150 广告印刷 单调队列
- 【例题】【单调队列】NKOJ2150 广告印刷
- 印刷
- 单调队列典型例题——广告印刷
- 印刷工艺- 喷墨印刷
- 2017第36届西安春季广告标识办公印刷LED光电照明产业博览会会刊(参展商名录)
- 印刷管理软件
- 丝网印刷
- 印刷工艺流程
- 一个简单的内联union问题
- 新开论坛,大家一起建设!
- C/C++中自定义信息输出——printf与宏的配合使用
- 疯牛 nyist586(二分答案)
- 【LeetCode】Merge Sorted Array ---合并数组
- 广告印刷
- 典型的Top K算法_找出一个数组里面前K个最大数...或找出1亿个浮点数中最大的10000个...一个文本文件,找出前10个经常出现的词,但这次文件比较长,说是上亿行或十亿行,总之无法一次读入内存,
- CentOS 下安装Memcached服务器
- 内网挂载ISO镜像搭建yum源提供局域网安装
- java 中的 wait/notify 同步锁机制
- 5.4
- 黑马程序员_<<装饰设计模式>>
- 为什么同样的程序在别人机子上可以运行,在我的机子上报错呢?error C2011
- Windows下用模拟磁盘创建ASM磁盘组