백준 9465 스티커 - JAVA

2025. 3. 3. 19:30·알고리즘/백준

9465 문제 링크


https://www.acmicpc.net/problem/9465

 

문제 설명


 

입출력


 

코드


<Bottom-up 방식>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.io.*;
import java.util.*;
 
public class Main {
    static int sticker;
    static int[][] arr;
    static int[][] dp;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();
        sticker = Integer.parseInt(br.readLine());
        for (int s = 0; s < sticker; s++) {
            int num = Integer.parseInt(br.readLine());
            arr = new int[3][num+1];
            dp = new int[3][num+1];
            for (int i = 1; i < 3; i++) {
                StringTokenizer st = new StringTokenizer(br.readLine());
                for (int j = 1; j <= num; j++) {
                    arr[i][j] = Integer.parseInt(st.nextToken());
                } 
            } 
            dp[1][1] = arr[1][1];
            dp[2][1] = arr[2][1];
            sb.append(findMax(num)).append("\n");
        } 
        bw.write(sb.toString());
        bw.flush();
    }
    private static int findMax(int num) {
        int max = 0;
        for (int i = 2; i <= num; i++) {
            dp[1][i] = Math.max(dp[2][i-1], dp[2][i-2]) + arr[1][i];
            dp[2][i] = Math.max(dp[1][i-1], dp[1][i-2]) + arr[2][i];
        } 
        max = Math.max(dp[1][num], dp[2][num]);
        return max;
    }
}
Colored by Color Scripter
cs

 

<Top-down 방식>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.io.*;
import java.util.*;
 
public class Main {
    static int sticker;
    static int[][] arr;
    static int[][] dp;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringBuilder sb = new StringBuilder();
        sticker = Integer.parseInt(br.readLine());
        for (int s = 0; s < sticker; s++) {
            int num = Integer.parseInt(br.readLine());
            arr = new int[2][num];
            dp = new int[2][num];
            for (int i = 0; i < 2; i++) {
                StringTokenizer st = new StringTokenizer(br.readLine());
                for (int j = 0; j < num; j++) {
                    arr[i][j] = Integer.parseInt(st.nextToken());
                    dp[i][j] = -1;
                } 
            } 
            int result = Math.max(findMax(0, num-1), findMax(1, num-1));
            sb.append(result).append("\n");
        } 
        bw.write(sb.toString());
        bw.flush();
    }
    private static int findMax(int row, int col) {
        if (col < 0) {
            return 0;
        } 
        if (dp[row][col] != -1) {
            return dp[row][col];
        } 
        int pick = findMax(1-row, col-1) + arr[row][col];
        int skip = findMax(row, col-1);
        
        return dp[row][col] = Math.max(pick, skip);
    }
}
Colored by Color Scripter
cs

 

알고리즘 설명


여타 다른 DP문제들과 동일하게 바로 점화식을 구해야 하는 문제입니다. dp배열을 2차원 배열로 선언한 후, 해당 위치의 스티커를 선택할 지 아닐지에 따라 최댓값을 비교해 dp배열을 채워가는 간단한 문제입니다. 점화식은 아래와 같습니다.

해당 배열의 값을 선택한다면 다른 가로줄의 이전 세로줄에 누적된 최대값(dp[1-row][col-1])과 현재 선택한 원소의 값(arr[row][col])의 값을 더하고, 해당 배열의 값을 선택하지 않는다면, 해당 줄의 이전 세로줄에 누적된 최대값(dp[row][col-1])을 서로 비교하여야 합니다.

아래 arr배열과 dp배열을 표로 확인하면 확실하게 이해가 가실것입니다.

예제1의 첫번째 스티커
점화식으로 채운 dp 배열

탑다운과 바텀업 두 가지 방식으로 풀이가 가능하나 n의 크기가 10만이기 때문에, 탑다운 방식인 경우에 함수의 호출이 많아져 재귀호출 시, 스택프레임을 할당받고 해제하는 비용과 함수 자체의 호출 비용등을 고려했을 때, 바텀업(반복문)방식이 효율적이라고 할 수 있습니다. 점화식을 반복문과 재귀문에 내 입맛대로 적용할 수 있을 때까지 화이팅입니다...

 

코드 해석


스티커의 개수를 입력받아 테스트 케이스 개수를 저장하고, 각 테스트 케이스마다 스티커 점수를 저장할 배열과 DP 배열을 선언합니다. 이후 2행 n열의 스티커 점수를 입력받고, DP 배열의 첫 번째 열을 각각 초기화합니다. 이후 2열부터 마지막 열까지 순차적으로 탐색하면서, 현재 위치의 점수를 선택할 경우 대각선 방향의 이전 스티커 중 최댓값을 더해 DP 값을 갱신합니다. 최종적으로 마지막 열에서 두 행 중 더 큰 값을 찾아 결과를 출력합니다.

'알고리즘 > 백준' 카테고리의 다른 글

백준 15681 트리와 쿼리 - JAVA  (0) 2025.03.17
백준 1197 최소 스패닝 트리 - JAVA  (0) 2025.03.06
백준 14502 연구소 - JAVA  (0) 2025.03.03
백준 2206 벽 부수고 이동하기 - JAVA  (1) 2025.03.01
백준 1865 웜홀 - JAVA  (1) 2025.02.26
'알고리즘/백준' 카테고리의 다른 글
  • 백준 15681 트리와 쿼리 - JAVA
  • 백준 1197 최소 스패닝 트리 - JAVA
  • 백준 14502 연구소 - JAVA
  • 백준 2206 벽 부수고 이동하기 - JAVA
BIS's tech Blog
BIS's tech Blog
Welcome to Kanghyun's tech blog :)
  • BIS's tech Blog
    벼익숙의 기술 블로그
    BIS's tech Blog
  • 전체
    오늘
    어제
    • 분류 전체보기 (63) N
      • 알고리즘 (49) N
        • 백준 (40) N
        • 프로그래머스 (9)
      • CS 스터디 (14)
        • CS - JAVA (11)
        • CS - DB (3)
      • Spring (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    재귀
    CS
    알고리즘 고득점 kit
    동적 계획
    프로그래머스
    java
    DFS
    깊이 우선 탐색
    dp
    자료구조
    BFS
    백준
    기술질문
    bottom-up
    너비 우선 탐색
    Lv2
    브루트포스
    Top-Down
    Baekjoon
    완전탐색
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
BIS's tech Blog
백준 9465 스티커 - JAVA
상단으로

티스토리툴바