https://www.acmicpc.net/problem/14728
14728번: 벼락치기
ChAOS(Chung-ang Algorithm Organization and Study) 회장이 되어 일이 많아진 준석이는 시험기간에도 일 때문에 공부를 하지 못하다가 시험 전 날이 되어버리고 말았다. 다행히도 친절하신 교수님께서 아래와
www.acmicpc.net
코드설명
배낭문제(냅색, KnapSack) + DP(Dynamic Programming)를 활용하는 문제입니다.
일반적인 배낭문제로써, 배낭문제의 로직을 적용하면 해결할 수 있습니다.
시간초과가 발생하기에 dp[101][100001] 을 사용합니다. 각 레벨(101)가지에서의 공부시간별( 100001 )로 최대 점수를 저장합니다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int N, M, H, T;
public static int answer = 0;
public static int[] arr;
public static int[] studyTime, studyScore;
public 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());
T = Integer.parseInt(st.nextToken());
studyTime = new int[N];
studyScore = new int[N];
dp = new int[101][100001];
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine());
studyTime[i] = Integer.parseInt(st.nextToken());
studyScore[i] = Integer.parseInt(st.nextToken());
}
System.out.println(simulate(0, T));
}
public static int simulate(int level, int leftTime) {
if(leftTime < 0) return 0;
if(level >= N) return 0;
if(dp[level][leftTime] > 0) return dp[level][leftTime];
int temp1 = 0;
if(leftTime - studyTime[level] >= 0) {
temp1 = studyScore[level] + simulate(level + 1, leftTime - studyTime[level]);
}
int temp2 = simulate(level + 1, leftTime);
return dp[level][leftTime] = Math.max(temp1, temp2);
}
}
다르게 풀어본코드입니다.
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 int N, M, C, T;
public static Study[] study;
public static int[][] dp;
public static int answer = 0;
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());
T = Integer.parseInt(st.nextToken());
study = new Study[N];
dp = new int[N][10001];
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine());
int inputK = Integer.parseInt(st.nextToken());
int inputS = Integer.parseInt(st.nextToken());
study[i] = new Study(inputK, inputS);
Arrays.fill(dp[i], -1);
}
answer = simulate(0, T);
System.out.println(answer);
}
public static int simulate(int level, int curT) {
if(curT < 0) return 0;
if(level >= N) return 0;
if(dp[level][curT] != -1) return dp[level][curT];
if(curT == 0) return 0;
int resultA = 0, resultB = 0;
if(curT - study[level].K >= 0) {
resultA = study[level].S + simulate(level + 1, curT - study[level].K);
}
resultB = simulate(level + 1, curT);
return dp[level][curT] = Math.max(resultA, resultB);
}
}
class Study{
int K;
int S;
public Study(int K, int S) {
this.K = K;
this.S = S;
}
}