Algorithm

[백준] 가장 큰 정사각형 1915번 (c++)

salmon16 2021. 3. 31. 13:23

출처 : 1915번: 가장 큰 정사각형 (acmicpc.net)

 

1915번: 가장 큰 정사각형

첫째 줄에 n, m(1 ≤ n, m ≤ 1,000)이 주어진다. 다음 n개의 줄에는 m개의 숫자로 배열이 주어진다.

www.acmicpc.net

풀이 방법

dp 문제이다 문제를 쪼개는 방법이 중요하다.

쪼갤 때 사각형의 가장 왼쪽 위 배열을 기준으로 그 정사각형의 한 변의 길이를 기록한다.

가장 큰 정사각형의 변의 길이를 제곱하여 넓이를 구한다.

0000

1111

1111

0000

예를 들어 위 경우에서 왼쪽 위 모서리의 배열에 길이를 저장이면 dp[1][0] = 2, dp[1][1] = 2.. 이렇게 되지만

dp[2][0] 은 1이 된다 변의 길이가 2인 정사각형에 포함은 되지만 그 정사각형에서 왼쪽 위의 점이 아니기 때문이다

이렇게 문제를 쪼개면 [i][j]의 정사각형의 변의 길이는 [i+1][j], [i][j+1], [i+1][j+1]의 변의 길이중 가장 작은 것에다가 +1 을 한 것이 된다.( 겹치는 부분 때문에 그림 그려보면 이해 가능) 

그리고 기저 조건으로 i == n-1 or j == m-1 이 되면 그 보드의 값을 리턴하면 기저 조건까지 준비가 다 된다.(기저 조건을 확인 잘 못해서 시간을 좀 썼다)

bord 값이 1이면 재귀 호출을 해주고 0이면 return 0;을 해주면 된다.

#include <iostream>
#include <algorithm>
#include <memory.h> 
#include <vector>

using namespace std;

int n, m;
int dp[1001][1001];
int ans = 0;
int count(vector<vector<int>>& bord, int i, int j) {    
    if (i == n-1 || j == m-1) {        
        ans = max(ans, bord[i][j]);
        return bord[i][j];
    }
    if (dp[i][j] != -1) {                
        return dp[i][j];
    }
    if (bord[i][j] == 0) {
        return 0;
    }
    if (bord[i][j] == 1) {
        int ret = 0;        
        ret = min(count(bord, i + 1, j + 1), min(count(bord, i, j + 1), count(bord, i + 1, j))) + 1;
        ans = max(ans, ret);        
        dp[i][j] = ret;        
        return ret;
    }
    
}
int main(void) {
    cin >> n >> m;
    vector<vector<int>> bord(n);
    memset(dp, -1, sizeof(dp));
    for (int i = 0; i < n; i++) {
        string str;
        cin >> str;
        for (int j = 0; j < m; j++) {
            bord[i].push_back(str[j] -'0');            
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {            
            int trash = count(bord, i, j);
        }
    }
    cout << ans * ans << endl;
    return 0;
}

'Algorithm' 카테고리의 다른 글

[백준] 설탕 2839번 (c++)  (0) 2021.04.02
[algospot] 폴리오미노 (c++)  (0) 2021.04.01
[학교 과제] 프리랜서 (c++)  (0) 2021.03.30
[학교 과제] 카드덱 (c++)  (0) 2021.03.30
[백준] 퇴사 14501번 (C++)  (0) 2021.03.24