PS/BOJ
2579
easy16
2022. 4. 25. 22:54
계단오르기
포도주 마시기와 똑같은 문제.
단, 마지막 계단을 포함한다? -> 현재 포도주를 반드시 마셔야한다와 같은 의미로 포도주에서 처럼 두번 연속 마시지 않는 경우는 고려하지 않는다(더 쉽다)
arr: 10 20 15 25 10 20
dp : 10 30 35 55 65 75
1)
10
2)
10 =10
10 + 20 =30
3)
20+15 =35
10+15 =25
4)
10 + 20 + 25 =55
10 + 15 + 25 =45
5)
10 + 25 + 30 = 65
10 + 35 = 45
6)
35 + 10 + 20 = 65
55 + 20 = 75
점화식
dp[i] = Math.max(dp[i-2], dp[i-3] + arr[i-1]) + arr[i];
글로 풀어서 설명하면,
1칸 아래 계단을 밟았으므로 3칸 아래 계단의 최대값과 더해준다.
2칸 아래 계단에서의 최대값에서 현재 계단으로 2칸 넘어 옴.
둘중 큰녀석을 택한다.
//2579
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int[] arr;
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());
int N = Integer.parseInt(st.nextToken());
//
// arr = new int[N + 1];
// dp = new int[N + 1];
arr = new int[303];
dp = new int[303];
for (int i = 1; i <= N; ++i) {
st = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(st.nextToken());
}
/*Bottom-up*/
/*
dp[1] = arr[1];
dp[2] = arr[1] + arr[2];
for (int i = 3; i <= N; ++i) {
dp[i] = arr[i];
dp[i] = Math.max(dp[i - 3] + arr[i - 1], dp[i - 2]) + arr[i];
}
*/
/*Top-down*/
dfs(N);
/*
for (int v : dp)
System.out.print(v + " ");
System.out.println();
*/
System.out.println(dp[N]);
br.close();
}
static int dfs(int n) {
if(n < 2) {
return dp[n] = arr[n];
}
if( n == 2) {
return dp[2] = arr[1] + arr[2];
}
if(dp[n] == 0) {
dp[n] = arr[n];
dp[n] = Math.max( dfs(n-3) + arr[n-1], dfs(n-2)) + arr[n];
}
return dp[n];
}
}