728x90
개요
문제 링크
골드 5, DP
2차원 배열 내에서 0으로 이루어진 정사각형의 개수
접근
한 변의 길이가 여러 개인 정사각형을 모두 세 주어야 하는데 그럼 O(n^2)을 넘어가지 않나? 하고 생각.
일단 dp를 쓰고 O(n^2)안에 해결하는 방법은 인접한 것들만 봐줘야 하는데, 어디까지 보냐가 핵심.
dp에 저장할 내용은 왼쪽 위부터 만들어 내려올 수 있는 최대 정사각형의 길이 이게 되는 이유는 (x,y)까지의 최대 길이가 곧 (x,y)를 오른쪽 아래점으로 포함하는 정사각형의 개수가 됨. 왜냐하면 최대 길이 정사각형 내부에서는 모두 정사각형을 만들 수 있으니까.
왼쪽이랑 위는 반드시 봐줌. 최대 정사각형은 왼쪽과 위에서 만든 정사각형을 반드시 포함하기 때문. 이때 아래 케이스를 보자
011 112 12?
?에 들어갈 값이 2인 것은 머리로 알 수 있다. 하지만 왼쪽과 위만 비교하면 3을 출력하므로 왼쪽위까지 비교해야 한다.
Pseudo code
for (y = 세로)
for (x = 가로)
if (!dp[y][x])
continue;
dp[y][x] = min(왼,위,왼위)+1
Source code
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
using ld = long long;
ld dp[N][N];
ld test() {
int r, c, k;
cin >> r >> c >> k;
int x, y;
for (int i=0; i<r; i++)
for (int j=0; j<c; j++)
dp[i][j] = 1;
for (int i=0; i<k; i++) {
cin >> y >> x;
dp[y][x] = 0;
}
for (int i=1; i<r; i++)
for (int j=1; j<c; j++) {
if (!dp[i][j])
continue;
dp[i][j] = min(dp[i-1][j], dp[i][j-1])+1;
dp[i][j] = min(dp[i][j], dp[i-1][j-1]+1);
}
ld sum = 0;
for (int i=0; i<r; i++)
for (int j=0; j<c; j++)
sum += dp[i][j];
return sum;
}
int main() {
int t;
cin >> t;
for (int i=1; i<=t; i++)
printf("Case #%d: %lld\n",i,test());
}
728x90
'백준브실골 > DP' 카테고리의 다른 글
백준 27210, 신을 모시는 사당 (0) | 2023.02.12 |
---|---|
백준 11909, 배열 탈출 (0) | 2023.02.11 |
백준 17265, 나의 인생에는 수학과 함께 (0) | 2023.02.09 |
백준 2229, 조 짜기 (0) | 2023.02.09 |
백준 23317, 구슬 굴리기 (0) | 2023.02.08 |
백준 25634, 전구 상태 뒤집기 (0) | 2023.02.08 |
백준 25343, 최장 최장 증가 부분 수열 (0) | 2023.02.08 |
백준 16494, 가장 큰 값 (0) | 2023.02.08 |
댓글