dp는 너무 어렵다. 쉬운 난이도이지만 한참 생각하고 헤맸다..
dp에서 중요한 것은 가장 먼저 dp[i]가 무엇인지 정의하고 점화식을 찾는 것이다.
사실 p[i] + dp[i-1] 부분이 이해가 잘 되지 않았다. i번째 날짜의 상담을 선택했을 때 i번째 날의 수익을 더하는 것은 이해가 되지만, dp[i-1]을 더하는 것이 문제가 없을까라는 의문이 있었다.
만약 dp[i-1]에서 이전 날짜 중 i번째 상담을 선택하지 못하는 경우의 수가 포함되어 최대 수익이 산정됐다면 dp[i-1]을 더하는 것이 문제이지 않을까 싶었다.
근데 다시 생각해보니 dp[i-1] = i-1번째 날까지의 최대 수익이라는 것을 잊었다.
예를 들어 3일차 최대 수익을 고려할 때 dp[3-1]=dp[2]가 된다. 2일차를 선택한다면 상담이 5일이나 걸려서 3일차 상담을 못하겠지만 이는 dp[2]에는 반영되지 않는다. 어차피 상담 끝나는 기간인 2+5-1=6일차 dp값에 수익이 반영되기 때문이다.
dp에서 중요한 것은 처음 dp값을 무엇으로 정의했느냐와 점화식인걸 느꼈다.
dp 배열을 이용하여 이전까지의 최적의 값을 누적하여 활용해야함을 기억해야한다.
import java.util.*;
import java.io.*;
import java.awt.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int t[] = new int[n+2];
int p[] = new int[n+2];
int dp[] = new int[n+2];
for(int i=1; i<=n; i++){
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
t[i]=Integer.parseInt(st.nextToken());
p[i]=Integer.parseInt(st.nextToken());
}
for(int i=1; i<=n; i++){
dp[i]=Math.max(dp[i-1],dp[i]);
if(i+t[i]-1<=n)
dp[i+t[i]-1]=Math.max(dp[i+t[i]-1],dp[i-1]+p[i]);
}
System.out.println(Arrays.stream(dp).max().getAsInt());
}
}