[백준 14501번] 퇴사 with Java

guswls·2024년 4월 26일
0

알고리즘

목록 보기
8/39
post-custom-banner

문제


https://www.acmicpc.net/problem/14501



코드


import java.io.*;
import java.util.*;

class Main {
	static int N;
	static Work[] works;
	static int result = Integer.MIN_VALUE;

	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());

		works = new Work[N];
		for (int i = 0; i < N; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			works[i] = new Work(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
		}

		backTracking(0, 0);

		System.out.println(result);
	}

	static void backTracking(int idx, int pay) {
		if (idx >= N) {
			result = Math.max(result, pay);
			return;
		}

		int updatedDate = works[idx].date + idx;
		if (updatedDate <= N) {
			backTracking(updatedDate, pay + works[idx].pay);
		} else {
			backTracking(updatedDate, pay);
		}

		backTracking(idx + 1, pay);
	}

	static class Work {
		int date;
		int pay;

		Work(int day, int money) {
			this.date = day;
			this.pay = money;
		}
	}
}


문제 이해


  • 문제에 나온 표를 보면 문제를 쉽게 이해할 수 있다.
  • 상담에 걸리는 기간의 합이 N보다 작으면서상담의 비용의 합이 최대인 경우를 구하면 된다.


풀이 방법


  • 백트래킹으로 문제를 해결하였다.
  • 기본적으로 idx를 1씩 증가시키며 백트래킹을 진행한다.
  • works[idx].date + idx는 그 일을 수행한 후의 Date가 된다. 예를 들어 works[0]date가 3이라면, 그 일을 끝낸 후에는 3일째가 되는 것이다.
  • 위에서 구한 날짜가 N보다 작다면 day와 pay를 갱신한 후 dfs를 호출, 만약 크다면 더이상 pay를 갱신하지 말고 day만 갱신한다.
  • 만약 idx가 N보다 크거나 같다면, result와 pay중 더 큰 값을 비교하고 종료한다.


핵심 포인트


  • 배열을 활용한다면 1-base가 아닌 0-base를 사용하여야 한다.
  • 백트래킹을 활용해야한다는 것을 알 수 있어야 된다.
  • 백트래킹에서 각 분기별로 처리를 이해하고 있어야한다. 만약 일을 한 후의 date가 N보다 작냐, 크냐에 따라서 동작이 달라진다.


보완할 점 / 느낀 점


  • 문제를 봤을 때, dp라고 생각은 하였으나 어떻게 시작해야될지 감을 못잡아서 못풀었다.
  • 이번 문제의 경우, 조금 고민하다가 빠른 시간에 풀이를 봤다. 오래 봐도 답이 안나올 것 같았다.
  • 브루트포스, 백트래킹, dp모두 구현문제를 풀 때 중요한 알고리즘이지만, 아직 푸는데 익숙하지 않은 것 같다.
  • 이런 문제의 경우는 정말 좋은 문제인 것 같다. 꼭 다시 풀어봐야겠다.


참고자료


profile
안녕하세요
post-custom-banner

0개의 댓글