문제 파악
https://www.acmicpc.net/problem/1679

풀이
DP 문제이다.
동전 문제와 유사한 방법으로 풀 수 있다. (참고 : 동전)
풀이 단계는 다음과 같다.
DP 배열 선언 및 초기화
DP 배열은 정수를 만들기 위해 필요한 정수의 최소 사용 횟수를 저장한다.
예를 들어 DP[100]는 100원을 만들기 위해 필요한 정수의 최소 개수이다.
DP 배열의 최대 크기는 '가장 큰 후보 정수 * K + 2' 로 설정한다.
3,4,5 정수를 최대 10번 사용 가능하다면 51까지 연산을 필요로 한다.
보다 편한 연산을 위해 DP[0]은 0으로 초기화해 주고,
그 외의 원소는 '가장 큰 후보 정수 * K + 1' 로 초기화해주었다.
최솟값 계산
가장 작은 후보 정수부터 시작해 최솟값을 업데이트해 준다.
문제에서 친절하게도 후보 정수를 오름차순으로 정렬해 준 상태이기에 정렬은 필요 없다 👏
아래 과정을 후보 정수마다 반복하도록 한다.
- 후보 정수는 한 번 사용하면 해당 정수를 채울 수 있으므로 dp[num] = 1로 설정
- 주어진 후보 정수 다음(num+1)부터 시작해서 마지막 원소까지 dp 배열 업데이트
- dp[j] = min(dp[j], dp[j-num] + dp[num])
이긴 후보 판단
위에서 연산한 dp 배열을 돌며 k를 초과하는 경우 승자를 출력하면 된다
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int givenGameNum = Integer.parseInt(br.readLine());
StringTokenizer tok = new StringTokenizer(br.readLine(), " ");
int k = Integer.parseInt(br.readLine());
int[] nums = new int[givenGameNum];
for (int i = 0; i < givenGameNum; i++) {
nums[i] = Integer.parseInt(tok.nextToken());
}
final int MAX = nums[nums.length - 1] * k + 1;
int[] dp = new int[MAX + 1];
Arrays.fill(dp, MAX);
dp[0] = 0;
for (int num : nums) {
dp[num] = 1;
for (int j = num + 1; j <= MAX; j++) {
dp[j] = Math.min(dp[j], dp[j - num] + dp[num]);
}
}
for (int i = 1; i <= MAX; i++) {
if (dp[i] > k) {
System.out.println((i % 2 == 0 ? "holsoon" : "jjaksoon") + " win at " + i);
return;
}
}
}
}'Algorithm' 카테고리의 다른 글
| [프로그래머스] 77886 - 110 옮기기 (Java) (0) | 2025.03.27 |
|---|---|
| [백준] 17070 - 파이프 옮기기 1(Java) (0) | 2025.03.25 |
| [프로그래머스] 388353 - 지게차와 크레인(Java) (0) | 2025.03.19 |
| [백준] 1806 - 부분 합(Java) (0) | 2025.03.18 |
| [백준] 1394 - 암호(Java) (0) | 2025.03.13 |