2478 小B接水(很像单调栈,但不是,预处理递推最大值,逐位考虑贡献)

题目描述:

2478 小b接水

小b将n个宽度相同的积木顺序摆在一起,如下图所示。

现在她告诉你每个积木的高度(可能为0)。

她想知道如果她从高处倒下一杯水,最多有多少单位的水能被积木接住?

假设每个积木的宽度都为1。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,最多可以接 6 个单位的水(蓝色部分表示水)。 

 收起

输入

第一行一个正整数n,其中0<n≤50000;
第二行n个数表示从左到右每个积木的高度,以空格隔开,每个数不超过10000。

输出

一个数,表示最多可以接的水量

输入样例

12
0 1 0 2 1 0 1 3 2 1 2 1

输出样例

6

思路:

           乍一看挺像是单调栈的题目,但考虑半天也没想出怎么做,首先我们知道,

单调栈是找一个值前面或者后面比他大/小的最远位置,且中间不能出现破环单调

性的元素(可以出现单调栈好像也可以求出所有“低处”拐点,每一个拐点L,R之间区域

对应一个水坑。然后求对应体积即可。  

PS:这样单调栈的L,R求出的水坑是多个水坑,因为其可能跨过“上界”拐点。

          另一种巧妙的思路是,逐位考虑每一个柱子,如果该柱子上方有水,

那其高度一定==min(左最大值,右边最大值)-a[i]。然后叠加即可。

实现代码(递推最大值):

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int N=2e5+100;
int a[N];
int Left[N],Right[N];
int main()
{
	int n;
	while(cin>>n)
	{
		LL ans=0;
		for(int i=1;i<=n;i++)cin>>a[i];
		for(int i=1;i<=n;i++)Left[i]=max(Left[i-1],a[i]);
		for(int i=n;i>=1;i--)Right[i]=max(Right[i+1],a[i]);
		for(int i=1;i<=n;i++)
			ans+=min(Left[i],Right[i])-a[i];
		cout<<ans<<endl;
	}
	return 0;
}

实现代码一:

         单调栈错误思路。。。

The end;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值