
https://www.acmicpc.net/problem/7579
이문제를 접했을때 어떤 알고리즘을 풀어야 할지 몰라 풀이방법을 찾아보니
DP로 풀어야 함을 알 수 있었다.
int[][] dp배열을 선언하고
dp[i][j] 에서 i 는 i번째의 앱까지 고려하였을 경우를 의미하고
j는 가능한 비용의 경우의 수를 의미한다.
먼저 입력값을 받아 실행 중인 앱의 개수 N, 필요한 메모리 M,
각 앱의 메모리 사용량과 비활성화 비용을 각각 m과 c 배열에 저장한다.
DP 배열은 비용의 최대값(10000)까지 고려할 수 있도록 초기화한다
.
DP 계산 과정은 각 앱을 순차적으로 처리하면서 진행된다.
번째 앱을 고려할 때, 현재 비용 j로 확보 가능한 메모리를 갱신한다.
만약 j가 c[i]보다 크거나 같다면,
i번째 앱을 비활성화하는 경우와 하지 않는 경우 중 더 큰 메모리를 선택한다.
그렇지 않은 경우,
이전 앱까지의 결과를 그대로 유지한다.
DP 배열을 채우면서,
현재 확보한 메모리가 M 이상일 경우 해당 비용 j를 최소 비용으로 갱신한다.
마지막으로, 최소 비용을 출력하여 문제를 해결한다.
import java.io.*;
import java.util.Arrays;
import java.util.Map;
import java.util.StringTokenizer;
public class Main {
static int N,M,mininumAnswer=Integer.MAX_VALUE;
static int[] m,c;
static int[][] dp;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 실행되고 있는 앱수
M = Integer.parseInt(st.nextToken()); // 필요한 메모리수
m = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt).toArray();
c = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt).toArray();
dp = new int[N][10001];
//첫 원소를 포함하는 경우의 수 ~ 마지막원소를 포함하는 경우의수
for(int i = 0 ; i < N ; i++) {
int cost = c[i];
int memory = m[i];
for (int j = 0; j < 10001; j++) {
if (i == 0){
if (j >= cost) dp[i][j] = memory;
}else{
if (j >= cost){
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-cost]+memory);
}else {
dp[i][j] = dp[i-1][j];
}
}
if(dp[i][j] > M){
mininumAnswer = Math.min(mininumAnswer,j);
}
}
}
System.out.println(mininumAnswer);
}
}
'Algorithm & Data Structures > BOJ' 카테고리의 다른 글
b9466. 텀 프로젝트 (0) | 2024.12.31 |
---|---|
b9295. LCS2 (1) | 2024.12.27 |
b7453. 합이 0인 네정수 (1) | 2024.12.20 |
b2623. 음악프로그램 (0) | 2024.12.17 |
b1024. 수열의 합 (0) | 2024.12.15 |