Skip to content

Commit

Permalink
day7: (2) dp/2156, dp/11053
Browse files Browse the repository at this point in the history
  • Loading branch information
CheolHoJung committed Apr 2, 2019
1 parent 644df65 commit 3835553
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 0 deletions.
89 changes: 89 additions & 0 deletions dp/가장_긴_증가_부분_수열.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package test.boj.dp;

import java.io.*;
import java.util.Arrays;

public class __가_부분_수열 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

int n = Integer.parseInt(br.readLine());
int[] numbers = Arrays.stream(("0 " + br.readLine()).split(" ")).mapToInt(Integer::parseInt).toArray();

System.out.println(solution(n, numbers));

br.close();
bw.flush();
bw.close();
}

// @Test
// public void test() {
// assertThat(solution(6, new int[]{0, 10, 20, 10, 30, 20, 50}))
// .isEqualTo(4);
// }

// 자신보다 작은 숫자들의 부분수열에서 길이가 가장 큰 경우를 구해야 한다. -> dp[i - 1], Math.max 사용
// 자신보다 작은 숫자들의 부분수열에서 길이가 같은 경우는 하나만 선택해도 상관없다.

// maxLengthOfSmallerNumbers(i) = numbers[i]보다 작은 숫자들의 부분수열에서 길이가 가장 큰 부분수열의 길이
// dp[i] = maxLengthOfSmallerNumbers(i) + 1

// i 0 1 2 3 4 5 6
// numbers 0 | 10 20 10 30 20 50
// dp 0 | 1 2 1 3 2 4
private static int solution(int n, int[] numbers) {
int[] dpOfLength = new int[1_010];
int maxLength = 0;

for (int i = 1; i <= n; i++) {
dpOfLength[i] = maxLengthOfSmallerNumbers(dpOfLength, numbers, i) + 1;
maxLength = Math.max(maxLength, dpOfLength[i]);
}
return maxLength;
}

private static int maxLengthOfSmallerNumbers(int[] dp, int[] numbers, int i) {
int result = 0;
int now = numbers[i];
for (int j = 1; j < i; j++) {
int prev = numbers[j];
if (now > prev) {
result = Math.max(result, dp[j]);
}
}
return result;
}

// 다음 코드처럼 dp 배열에 오름차순 수열을 만들어버리는 방법도 있다.
// 앞 단계에서 큰 숫자가 dp에 저장된다 하더라도
// D[j] >= A[i] 조건에 의해 다시 작은 숫자로 갱신된다.
// for (int i = 0; i < N; i++) {
// D[i] = Integer.MAX_VALUE;
// }
//
// for (int i = 0; i < N; i++) {
// for (int j = 0; j < D.length; j++) {
// if (D[j] >= A[i]) {
// D[j] = A[i];
// break;
// }
// }
// }
//
// for (int j = 0; j < D.length; j++) {
// if (D[j] < Integer.MAX_VALUE && D[j] > 0) {
// count++;
// }
// }
// Ex) dp = [1 2 3, .......], 정답 3
// index 0 1 2 3 4 5 6 7 8 9 10
// nums 3 1 1 2 1 1 1 1 1 1 3
// i=0, j=0 3
// i=1, j=0 1 <- 앞단계에서 3이 저장되더라도 i = 1, j = 0인 시점에서
// if (D[j] >= A[i]) { D[j] = A[i]; } 구문에 의해 더 작은 수인 1로 교체된다.
// -> D[j] = 3, A[i] = 1
// i=2, j=1 1 2
// i=10, j=3 1 2 3 <- 종료, 정답 3개
}
76 changes: 76 additions & 0 deletions dp/포도주_시식.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package test.boj.dp;

import java.io.*;

public class 포도주_시식 {

public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

int N = Integer.parseInt(br.readLine());
int[] wines = new int[N + 1];
for (int i = 1; i <= N; i++) {
wines[i] = Integer.parseInt(br.readLine());
}

System.out.println(solution(N, wines));

br.close();
bw.flush();
bw.close();
}

// @Test
// public void test() {
// assertThat(solution(1, new int[]{0, 6}))
// .isEqualTo(6);
// assertThat(solution(2, new int[]{0, 6, 10}))
// .isEqualTo(16);
// assertThat(solution(3, new int[]{0, 6, 10, 13}))
// .isEqualTo(23);
// assertThat(solution(4, new int[]{0, 6, 10, 13, 10}))
// .isEqualTo(29);
// assertThat(solution(4, new int[]{0, 10, 6, 13, 10}))
// .isEqualTo(33);
// assertThat(solution(6, new int[]{0, 6, 10, 13, 9, 8, 1}))
// .isEqualTo(33);
// assertThat(solution(6, new int[]{0, 1, 10, 13, 9, 8, 6}))
// .isEqualTo(37);
// }


// 1. 내가 현재의 포도주를 먹지 않았을 경우 (dp[i - 1])
// 2. 현재의 포도주를 마시고 이전 꺼를 안마실 경우 (wine[i] + dp[i - 2]
// 3. 현재와 이전 포도주 모두를 마신 경우 (wine[i] + wine[i - 1] + Dp[i - 3])
//
// wine 0 6 10 13 9 8 1
// dp 0 6 16 23 28 33 33
// 1. x x x 16 23 28 33
// 2. x x x 19 25 31 29
// 3. x x x 23 28 33 32
//
// wine 0 1 10 13 9 8 6
// dp 0 1 11 23 23 31 37
// 1. x x x 11 23 23 31
// 2. x x x 14 20 31 29
// 3. x x x 23 23 28 37
private static int solution(int N, int[] wines) {
int[] dp = new int[10_010];
for (int i = 1; i < 3 && i <= N; i++) {
if (i == 1) {
dp[i] = wines[1];
continue;
}
dp[i] = wines[i] + wines[i - 1];
}

for (int i = 3; i <= N; i++) {
int result = Math.max(dp[i - 1], wines[i] + dp[i - 2]);
result = Math.max(result, wines[i] + wines[i - 1] + dp[i - 3]);
dp[i] = result;
}

return dp[N];
}
}

0 comments on commit 3835553

Please sign in to comment.