알고리즘/백준 문제 풀이
[BOJ] 1915. 가장 큰 정사각형
바켱서
2020. 7. 12. 19:42
https://www.acmicpc.net/problem/1915
접근 방법
정사각형이 되는 경우를 생각해보았다.
- 현재 꼭짓점(x,y)에서 (x-1,y) (x,y-1) (x-1,y-1)이 모두 true라면 정사각형이다.
처음에는 재귀적으로 호출을 해서 정사각형을 체크하려 해주었음
- 당연히 시간 초과...
어떻게 하면 체크 한 것을 가지고 있으면서 정사각형이 최대가 되는지에 대한 생각...
- index는 1
1000, 11000이 모두 고정적이다. → 메모지에이션을 쓰면 되지 않을까?
동적프로그램을 생각해보았다.
위, 왼쪽, 왼쪽위 대각선이 모두 1일 경우
위, 왼쪽, 왼쪽위 대각선의 최소값에 +1을 더한값이 가장 큰 정사각형이 된다.
- 위, 왼쪽, 왼쪽위 대각선이 1일 경우
cache[i][k] = max( cache[i-1][k], cache[i-1][k-1], d[i][k-1]) + 1이 된다.
- 위, 왼쪽, 왼쪽위 대각선이 0이 포함된 경우
map[i][k]가 true이면 d[i][j] 는 1
map[i][j]가 false이면 d[i][j] 는 0 이 된다.
예시
Need Know
- DP
전체 코드 ( Java )
import java.io.*;
import java.util.StringTokenizer;
class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
static int N;
static int M;
static boolean[][] map;
static int[][] cache;
static int ans = 0;
public static void main(String[] args) throws IOException {
set();
solve();
bw.flush();
bw.close();
br.close();
}
static void set() throws IOException {
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new boolean[N+1][M+1];
cache = new int[N+1][M+1];
for(int i=1; i<N+1; i++){
String str = br.readLine();
for(int k=1; k<M+1; k++){
map[i][k] = str.charAt(k-1) == '1' ;
if(map[i][k]) cache[i][k] = 1;
}
}
}
static void solve() throws IOException {
for(int i=1; i<N+1; i++){
for(int k=1; k<M+1; k++){
if(map[i-1][k] && map[i-1][k-1] && map[i][k-1]){
int temp = Math.min(cache[i-1][k], cache[i-1][k-1]);
cache[i][k] = Math.min(temp, cache[i][k-1]) + 1;
}
ans = Math.max(cache[i][k], ans);
}
}
bw.write(ans*ans+"");
}
}