본문 바로가기

Problem Solving/BOJ 백준

[ BOJ 백준 1725번 - 히스토그램 ] 해설 및 코드

 

https://www.acmicpc.net/problem/1725

 

1725번: 히스토그램

문제 히스토그램에 대해서 알고 있는가? 히스토그램은 아래와 같은 막대그래프를 말한다. 각 칸의 간격은 일정하고, 높이는 어떤 정수로 주어진다. 위 그림의 경우 높이가 각각 2 1 4 5 1 3 3이다. 이러한 히스토그램의 내부에 가장 넓이가 큰 직사각형을 그리려고 한다. 아래 그림의 빗금 친 부분이 그 예이다. 이 직사각형의 밑변은 항상 히스토그램의 아랫변에 평행하게 그려져야 한다. 주어진 히스토그램에 대해, 가장 큰 직사각형의 넓이를 구하는 프로그램을

www.acmicpc.net

 

목적

왼쪽과 그림과 같은 히스토그램에서 오른쪽 그림과 같은 직사각형 넓이의 최대값을 구한다.

접근법

1. 분할정복 알고리즘으로 접근하자. (백준 2104 - 부분배열 고르기 문제와 같이 스위핑 알고리즘으로 접근할 수도 있다.)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<iostream>
#include<cmath>
using namespace std;
 
int a[100001];
int maxSize(int start,int end){
    if(start==end)return a[end];
    
    int mid=(start+end)/2;
    int lo=mid,hi=mid+1;
    int height=min(a[lo],a[hi]);
    int ret=height*2,tmp;
    
    while(start<lo||hi<end){
        if(start==lo) tmp=++hi;
        else if(hi==end) tmp=--lo;
        else if(a[lo-1]<a[hi+1]) tmp=++hi;
        else tmp=--lo;
        
        height=min(height,a[tmp]);
        ret=max(ret,height*(hi-lo+1));
    }
    
    return max(ret,max(maxSize(start, mid),maxSize(mid+1,end)));
}
 
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n;cin>>n;
    for(int i=0;i<n;++i)cin>>a[i];
    cout<<maxSize(0, n-1);
}
 
 

 

 

문제 설명과 코드에 대한 피드백은 언제나 환영합니다.

 다양한 의견 댓글로 남겨주세요.