SDU 프로그램 설계 생각 Week5- 가장 큰 사각형 작업 A-

프로그램 설계 생각 Week5- 작업

A- 가장 큰 직사각형

기술

히스토그램에 히스토그램에서 가장 큰 사각형 영역을 찾을 수 있습니다. 예를 들어, 왼쪽에서 오른쪽으로 히스토그램의 다음 상고 2, 1, 4, 5, 1, 3, 3, 그들은 넓은 1, 최대 사각형 음영되어있다.
그림 삽입 설명 여기입력 데이터의 세트를 복수 포함하는 방법. 각 데이터 세트는 정수로 N 작은 직사각형 히스토그램 표현하면 생각할 수가 1 <= N <= 100000 다음 정수, ..., HN, 만족 0 <= 하이 <= 1000000000. 이러한을 H1 다음 N 왼쪽 히스토그램 높이의 각각의 작은 사각형의 디지털 표현을 오른쪽에 각각의 작은 사각형의 폭은 1이다. 끝에서 0으로 테스트 데이터.
각 라인에 대한 테스트 데이터 출력 정수 않음을 나타낸다.

견본

input:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

output:
8
4000

생각

각각의 작은 직사각형의 높이를 제한하기 위해, 왼쪽과 오른쪽의 최대 연장이 한번에 큰 사각형은 작은 직사각형 직사각형베이스 모두 작은 구형 이러한 계산에서 최대로 확장 될 수 얻을 수 있습니다 마지막으로, 최대 복용하면 답을 얻을 수 있습니다.
스택의 단조의 배열 대신에, 여기에서 사용 생각 모노톤 스택, 스택은 아래에서 스택의 상단으로 증가된다.
사각형 상단 요소보다 큰 경우에는 우선, 제 검색에 기초하여 상기 히스토그램으로부터 제 사각형이 적은, 즉 오른쪽 끝 점의 온도보다 오른쪽 신장을 시작하여 최상위 요소는이 요소 밖으로 내밀어 태그 스택의 상단이 사각형보다 클 수 없습니다 때까지 오른쪽 테두리 후,이 사각형은, 그래서 과정 전반에 걸쳐 오른쪽 경계 모두에서이 표시됩니다 사각형이 다음 스택에 추가되고, 스택에 배치하고,주기의 종료 후 이들이 오른쪽 경계가 N이라고 이하 그 직사각형의 우측보다 여전히 가지고 직사각형 스택 나타낸다.
같은 방법을 찾고 왼쪽, 이하 각 사각형의 첫 번째 요소를 찾을 수 있습니다.
각 사각형의 경계 주위를 찾을 수는 가장 큰 사각형으로 간주 될 수있다.

요약

이 직사각형의 높이가 결정되면, 좌측 종점 더 좌측이어야 오른쪽 오른쪽 지점에 사각형의 유일하게 가능한 최대 영역
좌측 시점이 시점의 제 작은 높이의 수가 적절한 종점을 결정할 수있다 결정될 왼쪽 이것은 오른쪽 첫 번째 포인트 높이 소수 인
두 좌우측 단부 지점의 각각의 상위 점의 스택 프로세싱에 스택 최상부에 더미의 바닥으로부터 단조롭게 증가시킨다.

여기에 우리가 편리한 아웃으로 대신 스택 요소의 배열을 사용할 수 있습니다 만의 스택 상단 인덱스 변경해야
참고 : 0 <= 안녕하세요 <= 1000000000 결과 사용되도록 오래 오래 기억, 그렇지 않으면이 초과 될 수 있습니다.

코드

#include <iostream>

using namespace std;
int n;
int a[100010],L[100010],R[100010],s[100010];

int main()
{
	while (true) {
		cin >> n;
		if (n == 0)break;
		for (int i = 0; i < n; i++)
			cin >> a[i];
		long long ans = 0;
		int  top = -1;		//栈顶
		for (int i = 0; i < n; i++) {		//搜索每个元素往右第一个小于它的元素
			while (top>=0 && a[i]<a[s[top]]) {
				R[s[top]] = i;
				top--;
			}
			s[++top] = i;
		}
		while (top >=0)
			R[s[top--]] = n;
		top = -1;
		for (int i = n - 1; i >= 0; i--) {		//搜索每个元素往左第一个小于它的元素
			while (top >=0 && a[i] < a[s[top]]) {
				L[s[top]] = i;
				top--;
			}
			s[++top] = i;

		}
		while (top >= 0)
			L[s[top--]] = -1;

		for (int i = 0; i < n; i++)
			if (ans < (long long)a[i] * (R[i] - L[i] - 1))ans = (long long)a[i] * (R[i] - L[i] - 1);

		
		cout << ans << endl;
	}
}


게시 21 개 원래 기사 · 원 찬양 5 · 조회수 782

추천

출처blog.csdn.net/weixin_44578615/article/details/104977224