P1901 ,P1823单调栈

先放链接
P1901
P1823
单调栈讲解:视频

以找到左边第一个大于它的数为例:

大致意思就是:
一个数 A 的左边第一个最大数 Q 确定后,对于下一个数 B

Q_ _ _ _ _ _A B

如果 A > B
那 B 左边第一个大的数就是 A ,
如果 A <= B , 那就说明:包括 A 在内的,从 B 到 Q 的所有数都比 B 小,则 B 左边一个的大的数就是 Q

由此可得到代码:(具体有两种写法,在下面两个代码中分别展示)
for(int i=1;i<=n;i++){
____while(arr[s.top()]<=arr[i]) s.pop();
____res[i]=arr[s.top()]
____s.push(i)
}

因为 Q 和 A 中间所有比 A 小的数都被删除了,所以栈是单调减的

以此为基础得到P1901代码:

P1901 AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL n,h[1000010],e[1000010],res[1000010],ans;
stack<LL> s;
int main() {
	s.push(0);
	h[0]=LLONG_MAX;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>h[i]>>e[i];
	}
	for(int i=1;i<=n;i++)
	{
		while(h[s.top()]<=h[i]) s.pop();
		res[s.top()]+=e[i];
		s.push(i);
	}
	while(!s.empty()) s.pop();
	h[n+1]=LLONG_MAX;
	s.push(n+1);
	for(int i=n;i>=1;i--)
	{
		while(h[s.top()]<=h[i]) s.pop();
		res[s.top()]+=e[i];
		s.push(i);
	}
	sort(res+1,res+1+n);
	cout<<res[n];
	return 0;
}

对于P1823
因为栈中所有数是递减的,所以新的 heigh 来到时,在 pop 停止前的所有数都能和它对望,而原数列中被删除的数 E ,因为肯定小于栈中的一个数 W,所以有 E < W <= heigh , E 和 heigh 无法对望,故不会影响计数,
同时,因为等高的栈中数也会被删除,而登高的 W W height 也能对望,故要想办法统计与 heigh 登高的栈中数,可以使用 pair( heigh ,times )

P1823 AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
typedef pair<LL,LL> par;
LL n,h,ans;
stack<par> s;
int main() {
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>h;
		par p(h,1);
		while(!s.empty()&&s.top().first<=h)
		{
			ans+=s.top().second;
			if(s.top().first==h) p.second+=s.top().second;
			s.pop();
		}
		if(!s.empty()) ans++;
		s.push(p);
	}
	cout<<ans;
	return 0;
}
posted @   石磨豆浆  阅读(1)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示