#include <iostream>
#include <algorithm>
using namespace std;
#define MAXN 10
#define INF 987654321
int list[MAXN][MAXN];
int ret = INF;
int cnt;
int type[5] = { 5, 5, 5, 5, 5 };
void dfs(int y, int x) {
if (x == MAXN) {
dfs(y + 1, 0);
return;
}
if (y == MAXN) {
//다 확인했으면 최소 값 확인
ret = min(ret, cnt);
return;
}
if (list[y][x] == 0) {
dfs(y, x + 1);
return;
}
for (int len = 4; len >= 0; len--) {
if (type[len] == 0 || y + len >= MAXN || x + len >= MAXN) continue;
bool is_zero = false;
for (int i = 0; i <= len; i++) {
for (int j = 0; j <= len; j++) {
if (list[i + y][j + x] == 0) {
is_zero = true;
break;
}
}
if (is_zero) break;
}
if (is_zero) continue;
for (int i = 0; i <= len; i++) {
for (int j = 0; j <=len; j++) {
list[i + y][j + x] = 0;
}
}
cnt++;
type[len]--;
dfs(y, x + len);
for (int i = 0; i <= len; i++) {
for (int j = 0; j <= len; j++) {
list[i + y][j + x] = 1;
}
}
cnt--;
type[len]++;
}
}
int main() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
scanf("%d", &list[i][j]);
}
}
dfs(0, 0);
if (ret == INF) {
printf("%d\n", -1);
}
else {
printf("%d\n", ret);
}
return 0;
}
1. 첫 번째는 그리디로 가장 큰 종이부터 붙였지만 작은 종이를 먼저 붙이는 경우가 존재해서 불가능해서 브루트 포스로 다시 생각.
2. 5개 종이를 채우는 순서를 나열하면 5!가지이므로 그 순열로 dfs 돌렸으나 실패 -> 종이를 앞에서 부터 순서대로 채우지 않는 경우에서 반례 발생
3. dfs 다시 설계. 첫 줄부터 1~5번 종이를 모두 시도해보면서 dfs로 완전탐색을 시도한다. -> 올바른 dfs이므로 성공
** dfs, bfs 설계 방식이 자꾸 순열, 조합 방식으로 접근하게된다. 올바른 완전 탐색 설계를 할 수 있도록 조심할 것.