首页 > 代码库 > 每日一dp(1)——Largest Rectangle in a Histogram(poj 2559)使用单调队列优化
每日一dp(1)——Largest Rectangle in a Histogram(poj 2559)使用单调队列优化
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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。