백준 1495 : 기타리스트

전준형·2021년 7월 14일
0

백준

목록 보기
24/27

문제

Day Of Mourning의 기타리스트 강토는 다가오는 공연에서 연주할 N개의 곡을 연주하고 있다. 지금까지 공연과는 다른 공연을 보여주기 위해서 이번 공연에서는 매번 곡이 시작하기 전에 볼륨을 바꾸고 연주하려고 한다.

먼저, 공연이 시작하기 전에 각각의 곡이 시작하기 전에 바꿀 수 있는 볼륨의 리스트를 만들었다. 이 리스트를 V라고 했을 때, V[i]는 i번째 곡을 연주하기 전에 바꿀 수 있는 볼륨을 의미한다. 항상 리스트에 적힌 차이로만 볼륨을 바꿀 수 있다. 즉, 현재 볼륨이 P이고 지금 i번째 곡을 연주하기 전이라면, i번 곡은 P+V[i]나 P-V[i] 로 연주해야 한다. 하지만, 0보다 작은 값으로 볼륨을 바꾸거나, M보다 큰 값으로 볼륨을 바꿀 수 없다.

곡의 개수 N과 시작 볼륨 S, 그리고 M이 주어졌을 때, 마지막 곡을 연주할 수 있는 볼륨 중 최댓값을 구하는 프로그램을 작성하시오. 모든 곡은 리스트에 적힌 순서대로 연주해야 한다.

입력
첫째 줄에 N, S, M이 주어진다. (1 ≤ N ≤ 100, 1 ≤ M ≤ 1000, 0 ≤ S ≤ M) 둘째 줄에는 각 곡이 시작하기 전에 줄 수 있는 볼륨의 차이가 주어진다. 이 값은 1보다 크거나 같고, M보다 작거나 같다.

출력
첫째 줄에 가능한 마지막 곡의 볼륨 중 최댓값을 출력한다. 만약 마지막 곡을 연주할 수 없다면 (중간에 볼륨 조절을 할 수 없다면) -1을 출력한다.

BOJ1495

접근

일반적인 DP 문제라 생각하고 접근했는데, 자료구조를 떠올리기 참 힘들었다. 노래가 진행될수록 2배로 분기가 갈리는 형태로 보아 트리로 짜야 하나 싶었는데, 멋진 풀이법을 찾게 되었다.

이차원 boolean 배열을 만들고, 배열 인자를 [곡 번호]'[현재볼륨]으로 주는 것이다. 현재 볼륨에 들어갈 수 있는 값은 0~M까지이고, 이 전 곡에서 존재 할 수 있는 현재볼륨에 볼륨의 차이를 더하거나 빼준 값이 0~M 사이에 존재한다면 True로 값을 정해준다.

결과는 마지막 곡 번호의 현재볼륨 중 True를 가진 가장 큰 값을 출력해준다.

코드

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int s = sc.nextInt();
		int m = sc.nextInt();

		boolean [][] dp = new boolean[n+1][m+1];
		dp[0][s] = true;
		
		for(int i = 1; i<=n; i++) {
			int now = sc.nextInt();
			for(int j = 0; j <= m; j++) {
				if(dp[i-1][j] && j + now <= m) 
					dp[i][j+now] = true;
				if(dp[i-1][j] && j - now >= 0)
					dp[i][j-now] = true;
			}
		}
		
		for(int i = m; i >= 0; i--) {
			if(dp[n][i]) {
				System.out.println(i);
				System.exit(0);
			}
		}
		System.out.println(-1);
	}
}
profile
한방에 맞게 해주세요

0개의 댓글