璟雯院

珺璟如晔,雯华若锦

用户工具

站点工具


icpc:problems:luogup1901
problems
名称发射塔
题目编号P1901
题目链接luogu.com.cn/…
来源Luogu
算法分类, 单调栈
难易程度容易

发射塔

想法

维护单调栈,即第i个元素往左看时,能看到的元素。对于第i个元素,先将栈内比它小的元素出栈,再将能量发射给第一个比它大的元素,即栈顶。往右看时,操作一致。

  1. 先将所有比第i个塔矮的塔出栈。
  2. 如果栈内还有塔,将第i个塔的能量发给栈顶元素。因为栈顶一定比第i个塔高。
  3. 将第i个塔入栈(第i+1个塔一定能看到第i个塔)

代码实现

#include<cstdio>
const int N = 1e6+10;
int sta[N], h[N], val[N], ans[N], top, n;
int main() {
	scanf("%d", &n);
	for(int i=1; i<=n; i++) {
		scanf("%d %d", &h[i], &val[i]);
	}
	top = 0;
	for(int i=1; i<=n; i++) {
		while(top > 0 && h[sta[top]] <= h[i])top--;
		if(top>0)
			ans[sta[top]] += val[i];
		sta[++top] = i;
	}
	top = 0;
	for(int i=n; i>=1; i--) {
		while(top > 0 && h[sta[top]] <= h[i])top--;
		if(top>0)
			ans[sta[top]] += val[i];
		sta[++top] = i;
	}
	int mx = 0;
	for(int i=1; i<=n; i++) 
		if(mx < ans[i])mx = ans[i];
	printf("%d", mx);
	return 0;
}

讲解代码

#include<cstdio>
const int N = 1e6+10;
int sta[N], h[N], val[N], ans[N], top, n;
int main() {
	scanf("%d", &n);
	for(int i=1; i<=n; i++) {
		scanf("%d %d", &h[i], &val[i]);//h第i个塔高度 val 第i个塔的能量
	}
	top = 0;
	for(int i=1; i<=n; i++) {//枚举1到n,处理第i个塔往左看的情况。
		while(top > 0 && h[sta[top]] <= h[i])top--;
		// 当栈不为空,且栈顶元素比第i个塔矮,说明:
		// 1. 栈顶在后续是看不见的:第i个塔挡住了
		// 2. 第i个塔不会将能量发给比它矮的。
		// top--:出栈
		if(top>0) // 当栈内有元素说明
				  // 1. 栈顶元素比第i个塔高
				  // 2. 第i个塔的能量会给第一个离他近的塔。栈顶的塔
			ans[sta[top]] += val[i];
		sta[++top] = i;//将第i个塔入栈
	}
	top = 0;//栈初始化,清空。
	for(int i=n; i>=1; i--) {//枚举n到1,处理第i个塔往右看的情况。
		while(top > 0 && h[sta[top]] <= h[i])top--;
		if(top>0)
			ans[sta[top]] += val[i];
		sta[++top] = i;
	}
	int mx = 0;
	for(int i=1; i<=n; i++) //在ans中求最大值。
		if(mx < ans[i])mx = ans[i];
	printf("%d", mx);
	return 0;
}
/app/www/public/data/pages/icpc/problems/luogup1901.txt · 最后更改: 2024/01/31 11:26 由 温婕莺