木板灌水问题(单调栈)

题意:地上从左到右竖立着N块木板,从1到n依次编号,如下图所示。我们知道每块木板的高度,在第n块模板右侧竖立着一块高度无限大的木板,现在对每块木板依次执行如下操作:对于第i块木板,我们从其右侧开始倒水,直到水的高度等于第i块木板的高度,倒入的水淹没ai块木板(如果木板左右两侧水的高度大于等于木板高度即可视为木板被淹没)。求n次操作后,所有ai的和为多少。

木板灌水问题(单调栈)_第1张图片

解决思路:

什么时候谁的高度会等于第i块木板的高度hi呢?当水向右边漫延遇到了一块高度大于等于hi的木板j,ai就等于木板i和木板j之间的木板数,所以我们可以利用单调栈来解决:插入时,判断栈顶是否比它大,如果比它小,将ai+1,如果比它大,则正常入栈

算法如下:

#include 
#include 
using namespace std;

class Node {
public:
	int id;
	int height;
};

int main() {

	int n = 0;
	cin >> n;
	stack monotonousStack;
	Node temp;
	int sum = 0;  //用来计算最后的和
	for (int i = 0; i < 5; ++i) {
		temp.id = i;
		cin >> temp.height;
		while (!monotonousStack.empty() && temp.height >= monotonousStack.top().height) {
			sum += i - (monotonousStack.top().id - 1);  
			monotonousStack.pop();
		}
		monotonousStack.push(temp);
	}
	while (!monotonousStack.empty()) {
		sum += n + 1 - (monotonousStack.top().id - 1);
	}
	
	cout << sum << endl;
	system("PAUSE");
	return 0;
}

 

你可能感兴趣的:(ACM算法习题)