Skip to content

Commit

Permalink
day6: (2) dp/2193, dp/9465
Browse files Browse the repository at this point in the history
  • Loading branch information
CheolHoJung committed Apr 1, 2019
1 parent 8624c5d commit 0abacfb
Show file tree
Hide file tree
Showing 2 changed files with 259 additions and 0 deletions.
161 changes: 161 additions & 0 deletions dp/스티커.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package test.boj.dp;

import org.junit.*;

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

import static org.assertj.core.api.Assertions.assertThat;

public class 스티커 {
static int[][] dp = new int[2][100_001];

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 tCase = Integer.parseInt(br.readLine());
for (int i = 0; i < tCase; i++) {
int n = Integer.parseInt(br.readLine());
int[][] numbers = new int[2][];
for (int j = 0; j < 2; j++) {
int[] s = Arrays.stream(br.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
numbers[j] = s;
}

bw.write(solution2(n, numbers) + "\n");
}
br.close();
bw.flush();
bw.close();
}

@Test
public void test2() {
assertThat(solution(5, new int[][]{
{50, 10, 100, 20, 40},
{30, 50, 70, 10, 60},
})).isEqualTo(260);

assertThat(solution(7, new int[][]{
{10, 30, 10, 50, 100, 20, 40},
{20, 40, 30, 50, 60, 20, 80},
})).isEqualTo(290);

assertThat(solution(1, new int[][] {
{1},
{1}
})).isEqualTo(1);

assertThat(solution(1, new int[][] {
{0},
{1}
})).isEqualTo(1);
}

// 대각선으로 이동하면서 값을 더해나감
// 한칸만 이동할 수 있는게 아니라, 두칸 이상도 이동 가능
// 그러나, 세칸의 경우를 보면 (위, 아래, 위) 혹은 (아래, 위, 아래)와 같이 한칸씩 이동해서도 도달할 수 있음
// 세칸을 한번에 이동한 것보다 한칸씩 3번 이동하면서 더한 값이 더 큰게 당연하므로, 한칸 혹은 두칸만 고려하면 됨
// dp[0 || 1][i] = Math.max(한칸 전, 두칸 전) + a[i]
private static int solution2(int n, int[][] numbers) {
dp[0][0] = dp[1][0] = 0;
dp[0][1] = numbers[0][0];
dp[1][1] = numbers[1][0];

for (int i = 2; i <= n; i++) {
dp[0][i] = Math.max(dp[1][i - 1], dp[1][i - 2]) + numbers[0][i - 1];
dp[1][i] = Math.max(dp[0][i - 1], dp[0][i - 2]) + numbers[1][i - 1];
}
return Math.max(dp[0][n], dp[1][n]);
}

@Test
public void test() {
assertThat(solution(5, new int[][]{
{50, 10, 100, 20, 40},
{30, 50, 70, 10, 60},
})).isEqualTo(260);

assertThat(solution(7, new int[][]{
{10, 30, 10, 50, 100, 20, 40},
{20, 40, 30, 50, 60, 20, 80},
})).isEqualTo(290);

assertThat(solution(1, new int[][] {
{1},
{1}
})).isEqualTo(1);

assertThat(solution(1, new int[][] {
{0},
{1}
})).isEqualTo(1);
}


// 10 30 10 50 100 20 40
// 20 40 30 50 60 20 80

// (1) 0 40 0 0 100 0 80

// (2) 10 40 10 50 100 0 80

// 첫 반복 -> 위아래좌우 비교했을 때 가장 큰놈 선택
// 두번째 반복 -> 선택되지 않은 놈들 중, 선택된 놈과 비교해서 교차되는 놈을 선택
// -> 좌우 선택된 놈들과 비교했을 때 모두 교차되는 경우가 아니라면 선택 불가
// 오답
private static int solution(int n, int[][] numbers) {
// 1 위, 2 아래
int[] selected = new int[n];

for (int i = 0; i < n; i++) {
int numUp = numbers[0][i];
int leftUp = i > 0 ? numbers[0][i - 1] : 0;
int rightUp = i < n - 1 ? numbers[0][i + 1] : 0;
int numDown = numbers[1][i];

if (numUp >= leftUp && numUp >= rightUp && numUp >= numDown) {
selected[i] = 1;
continue;
}

int leftDown = i > 0 ? numbers[1][i - 1] : 0;
int rightDown = i < n - 1 ? numbers[1][i + 1] : 0;
if (numDown >= leftDown && numDown >= rightDown && numDown >= numUp) {
selected[i] = 2;
continue;
}
}

int sum = 0;
for (int i = 0; i < n; i++) {
if (selected[i] != 0) {
sum += numbers[selected[i] - 1][i];
continue;
}

int leftSelected = i > 0 ? selected[i - 1] : 0;
int rightSelected = i < n - 1 ? selected[i + 1] : 0;

if (leftSelected != 0 && rightSelected == 0) {
selected[i] = 3 - leftSelected;
sum += numbers[selected[i] - 1][i];
continue;
}

if (rightSelected != 0 && leftSelected == 0) {
selected[i] = 3 - rightSelected;
sum += numbers[selected[i] - 1][i];
continue;
}

if(leftSelected != 0 && rightSelected == leftSelected) {
selected[i] = 3 - leftSelected;
sum += numbers[selected[i] - 1][i];
continue;
}
}

return sum;
}
}
98 changes: 98 additions & 0 deletions dp/이친수.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package test.boj.dp;

import org.junit.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

import static org.assertj.core.api.Assertions.assertThat;

public class 이친수 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println(solution2(Integer.parseInt(br.readLine())));
}

// 1
// 1
//
// 2
// 10
//
// 3
// 100
// 101
//
// 4
// 1000
// 1010
// 1001
//
// 5
// 10000
// 10010
// 10100
// 10001
// 10101
//
// 6
// 100000
// 100010
// 100100
// 101000
// 101010
// 100001
// 100101
// 101001
private static long solution2(int n) {
if (n < 2) return 1;
long[] dp = new long[n + 1];
dp[1] = dp[2] = 1;
for (int i = 2; i <= n; i++) {
// D[n]: D[n - 1] + D[n - 2]
// D[n - 1]: n번째 자리에 0이 오는 경우
// D[n - 2]: n번째 자리에 1이 오는 경우
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}

@Test
public void test2() {
assertThat(solution2(1))
.isEqualTo(1);
assertThat(solution2(90))
.isEqualTo(2880067194370816120L);
}

@Test
public void test() {
assertThat(solution2(1))
.isEqualTo(1);
// timeout
assertThat(solution2(90))
.isEqualTo(2880067194370816120L);
}

private static long solution(int n) {
Map<Integer, List<String>> dp = new HashMap<>();
dp.put(1, Arrays.asList("1"));

for (int i = 2; i <= n; i++) {
List<String> prev = dp.get(i - 1);

List<String> now = new ArrayList<>();
for (String prevNum : prev) {
now.add(prevNum + "0");
if (prevNum.endsWith("0")) {
now.add(prevNum + "1");
}
}
dp.put(i, now);
}

return dp.get(n).stream().count();
}
}

0 comments on commit 0abacfb

Please sign in to comment.