dfs(alp + 1, cop, cnt + 1, maxAlp, maxCop, problems, isVisited);
dfs(alp, cop + 1, cnt + 1, maxAlp, maxCop, problems, isVisited);
for (var p : problems) {
if (alp >= p[0] && cop >= p[1]) {
dfs(alp + p[2], cop + p[3], cnt + p[4], maxAlp, maxCop, problems, isVisited);
}
}
if (alp > maxAlp) alp = maxAlp;
if (cop > maxCop) cop = maxCop;
isVisited[alp][cop] = Math.min(isVisited[alp][cop], cnt);
if (alp == maxAlp && cop == maxCop) return;
단순히 위처럼 최댓값에 도달했을 경우에만 종료 조건을 잡으면, 수많은 경우의 수로 인해 에러가 발생한다. 답이 될 가능성이 없는 것들은 제외하여 경우의 수를 줄일 필요가 있다. (가지치기)
방문하지 않은 곳은 최댓값으로 초기화한다. 방문했다면 해당 알고력, 코딩력에 도달하기까지 걸린 시간을 갱신한다. 또 방문했다면, 시간이 단축되는 경우가 아니면 탐색을 종료한다. 이는 재귀가 수없이 깊어지고 많아지는 것을 방지한다.
if (isVisited[alp][cop] <= cnt) return;
isVisited[alp][cop] = Math.min(isVisited[alp][cop], cnt);
import java.util.*;
class Solution {
public int solution(int alp, int cop, int[][] problems) {
int maxAlp = -1;
int maxCop = -1;
for (var p : problems) {
maxAlp = Math.max(maxAlp, p[0]);
maxCop = Math.max(maxCop, p[1]);
}
int[][] isVisited = new int[151][151];
for (var row : isVisited) Arrays.fill(row, Integer.MAX_VALUE);
dfs(alp, cop, 0, maxAlp, maxCop, problems, isVisited);
return isVisited[maxAlp][maxCop];
}
void dfs(int alp, int cop, int cnt, int maxAlp, int maxCop, int[][] problems, int[][] isVisited) {
if (alp > maxAlp) alp = maxAlp;
if (cop > maxCop) cop = maxCop;
if (isVisited[alp][cop] <= cnt) return;
isVisited[alp][cop] = Math.min(isVisited[alp][cop], cnt);
if (alp == maxAlp && cop == maxCop) return;
dfs(alp + 1, cop, cnt + 1, maxAlp, maxCop, problems, isVisited);
dfs(alp, cop + 1, cnt + 1, maxAlp, maxCop, problems, isVisited);
for (var p : problems) {
if (alp >= p[0] && cop >= p[1]) {
dfs(alp + p[2], cop + p[3], cnt + p[4], maxAlp, maxCop, problems, isVisited);
}
}
}
}
import java.util.*;
class Solution {
public int solution(int alp, int cop, int[][] problems) {
int maxAlp = -1;
int maxCop = -1;
for (var p : problems) {
maxAlp = Math.max(maxAlp, p[0]);
maxCop = Math.max(maxCop, p[1]);
}
int[][] dp = new int[maxAlp + 1][maxCop + 1];
for (var row : dp) Arrays.fill(row, Integer.MAX_VALUE);
alp = Math.min(alp, maxAlp);
cop = Math.min(cop, maxCop);
dp[alp][cop] = 0;
for (int i = alp; i <= maxAlp; i++) {
for (int j = cop; j <= maxCop; j++) {
if (i < maxAlp) {
dp[i + 1][j] = Math.min(dp[i + 1][j], dp[i][j] + 1);
}
if (j < maxCop) {
dp[i][j + 1] = Math.min(dp[i][j + 1], dp[i][j] + 1);
}
for (var p : problems) {
if (i >= p[0] && j >= p[1]) {
int newAlp = Math.min(i + p[2], maxAlp);
int newCop = Math.min(j + p[3], maxCop);
dp[newAlp][newCop] = Math.min(dp[newAlp][newCop], dp[i][j] + p[4]);
}
}
}
}
return dp[maxAlp][maxCop];
}
}