一类需要用到单调队列的题目
Posted babydragon
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一类需要用到单调队列的题目相关的知识,希望对你有一定的参考价值。
直方图的最大矩形面积
n*m矩阵空地周长
水坑的最大储水量
一维
- 给h
- 给地面的高和天花板的高
- 地面是一个三角形的斜坡
二维
- 仅给地面的高
NYOJ 547
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
typedef long long ll;
ll a[310][310];
bool vis[310][310];
int n, m;
int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
struct node{
int x, y, v;
bool operator < (const node & oth)const
{
return v > oth.v; // 每一层都按从小到大的值排
}
};
priority_queue<node>pq;
void bfs()
{
ll ans = 0;
while (!pq.empty())
{
int x = pq.top().x, y = pq.top().y, v = pq.top().v;
pq.pop();
if (vis[x][y])
continue;
vis[x][y] = 1;
for (int i = 0; i < 4; i++)
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
int vv = a[xx][yy];
if (xx < n && xx > 1 && yy < m && yy > 1 && !vis[xx][yy])
{
if (vv < v) //若该点小于当前点,则可升高
{
ans += v - vv;
a[xx][yy] = v; //更新信息
}
pq.push({ xx, yy, a[xx][yy] });
}
}
}
cout << ans << endl;
}
int main(){
while (cin >> m >> n)
{
memset(vis, 0, sizeof vis);
while (!pq.empty())
pq.pop();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
if (i == 1 || j == 1 || i == n || j == m)
pq.push({ i, j, a[i][j] }); //先压入边界的点
}
bfs();
/*for (int i = 1; i <= n; i++, cout << endl)
for (int j = 1; j <= m; j++)
cout << a[i][j] << " ";*/
}
return 0;
}
以上是关于一类需要用到单调队列的题目的主要内容,如果未能解决你的问题,请参考以下文章