每日一dp(1)——Largest Rectangle in a Histogram(poj 2559)使用单调队列优化

来源:互联网 发布:韩服lol账号购买淘宝 编辑:程序博客网 时间:2024/04/30 04:57

Largest Rectangle in a Histogram

题目大意:

有数个宽为1,长不定的连续方格,求构成的矩形中最大面积


/************************************************************************//* 思路1.当前为n的面积如何与n-1相联系,dp[i][j]=max(dp[i-1][k]) , 0<k<=j描述:i为方块个数,j为高度但是此题目的数据对于高度太变态,h,1000000000 ,n,100000所以不可行(一般计算机为Ghz 相当于1S十几亿运算)思路2.此题目寻找的最大面积,对于一个方块来说则是以自己为中心左右两端比自己高的方块累计和与自己面积的乘积,取最大值。状态转移则可看作已知前面n-1个左边比自己高的的位置l[i],则如果该下标对应的数据比自己还高,继续往下找。利用了n-1的l[i]中数值优化:使用单调队列1. 即每次插入都从后往前找,找到不小于自己的,插入并抛弃该位置后面的数据2. 每次都从队头取元素,并及时淘汰过期数据此队列具有单调性,最大的永远在队头,对于没用的数据及时删除,过期数据也及时更新对应到此题目:q中存放的则是1.2.3.....i-1 的位置,更新的是比[i-1]大的元素,即比[i-1]大的元素都被更新                                                                     *//************************************************************************/#include <iostream>using namespace std;const int maxn=5+100000;int a[maxn];int q[maxn],l[maxn],r[maxn];int N,tail,front;__int64 ans,tmp;int main(){    int i;while(scanf("%d",&N),N){for(i=1;i<=N;i++)scanf("%d",a+i);tail=1;front=0;q[1]=1;for(i=2;i<=N;i++){while( front<tail && a[q[tail]]>a[i] )r[q[tail]]=i-1,tail--;q[++tail]=i;}while(front<tail)r[q[tail]]=N,tail--;tail=1;q[1]=N;for(i=N-1;i;i--){while( front<tail && a[q[tail]]>a[i] )l[q[tail]]=i+1,tail--;q[++tail]=i;}while(front<tail)l[q[tail]]=1,tail--;ans=0;for(i=1;i<=N;i++){tmp=r[i]-l[i]+1;tmp*=a[i];ans=ans>tmp?ans:tmp;}printf("%I64d\n",ans);}    return 0;}



1 0