문제

https://www.acmicpc.net/problem/18290
18290번: NM과 K (1)
크기가 N×M인 격자판의 각 칸에 정수가 하나씩 들어있다. 이 격자판에서 칸 K개를 선택할 것이고, 선택한 칸에 들어있는 수를 모두 더한 값의 최댓값을 구하려고 한다. 단, 선택한 두 칸이 인접
www.acmicpc.net
코드
#include <iostream>
using namespace std;
int arr[11][11];
int isVisited[11][11];
int maxN = -40000;
int n,m,k;
void dfs(int y, int x, int cnt, int sum){
sum+=arr[y][x];
cnt++;
if(cnt==k){
if(sum>maxN) maxN = sum;
return;
}
isVisited[y][x]++;
if(y-1>0) isVisited[y-1][x]++;
if(y+1<=n) isVisited[y+1][x]++;
if(x-1>0) isVisited[y][x-1]++;
if(x+1<=m) isVisited[y][x+1]++;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
if(isVisited[i][j]==0){
dfs(i, j, cnt, sum);
}
}
}
isVisited[y][x]--;
if(y-1>0) isVisited[y-1][x]--;
if(y+1<=n) isVisited[y+1][x]--;
if(x-1>0) isVisited[y][x-1]--;
if(x+1<=m) isVisited[y][x+1]--;
}
int main(){
cin >> n >> m >> k;
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
cin >> arr[i][j];
}
}
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
dfs(i, j, 0, 0);
}
}
cout << maxN;
return 0;
}
정리
처음에 isVisited배열을 bool로 선언해서 시간을 많이 잡아먹었던 문제다.
5 5 3
0 0 0 0 0
0 9 0 9 0
10 0 9 0 0
0 0 0 1 0
0 0 0 0 0
isVisited를 bool로 선언했을 경우 나올 수 있는 반례가 위 예시이다. 문제대로라면 9+9+10으로 28이 나와야 하지만 isVisited를 bool로 선언했을 경우에는 29가 나온다. 29는 10+10+9로 나온 결과이다. 이것은 선택한 칸들이 공통적으로 방문할 수 없는 경우를 고려하지 않아서 생긴 문제이다. 10을 처음에 방문처리를 했더라도 어떤 경우의 수에 의해 10의 방문처리가 false로 바뀌어 다시 10을 접근할 수 있다. 이 문제를 해결하기 위해서는 isVisited를 int로 선언하고 isVisited가 0인 경우에만 방문할 수 있도록 코드를 구현하면 해결할 수 있다.
참조
'Beakjoon > backtracking' 카테고리의 다른 글
| [백준] 10819번 차이를 최대로 (C++) - backtracking (0) | 2022.05.21 |
|---|---|
| [백준] 6603번 로또 (C++) - backtracking (0) | 2022.05.07 |
| [백준] 15657번 N과 M (8) (C++) - backtracking (0) | 2022.04.15 |
| [백준] 15656번 N과 M (7) (C++) - backtracking (0) | 2022.04.15 |
| [백준] 15655번 N과 M (6) (C++) - backtracking (0) | 2022.04.15 |