티스토리 뷰
1. 문제
상근이의 여동생 상냥이는 문방구에서 스티커 2n개를 구매했다. 스티커는 그림 (a)와 같이 2행 n열로 배치되어 있다. 상냥이는 스티커를 이용해 책상을 꾸미려고 한다.
상냥이가 구매한 스티커의 품질은 매우 좋지 않다. 스티커 한 장을 떼면, 그 스티커와 변을 공유하는 스티커는 모두 찢어져서 사용할 수 없게 된다. 즉, 뗀 스티커의 왼쪽, 오른쪽, 위, 아래에 있는 스티커는 사용할 수 없게 된다.
모든 스티커를 붙일 수 없게된 상냥이는 각 스티커에 점수를 매기고, 점수의 합이 최대가 되게 스티커를 떼어내려고 한다. 먼저, 그림 (b)와 같이 각 스티커에 점수를 매겼다. 상냥이가 뗄 수 있는 스티커의 점수의 최댓값을 구하는 프로그램을 작성하시오.
입)
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 n (1 ≤ n ≤ 100,000)이 주어진다. 다음 두 줄에는 n개의 정수가 주어지며, 각 정수는 그 위치에 해당하는 스티커의 점수이다. 연속하는 두 정수 사이에는 빈 칸이 하나 있다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.
출)
각 테스트 케이스 마다, 2n개의 스티커 중에서 두 변을 공유하지 않는 스티커 점수의 최댓값을 출력한다.
2. 풀이
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
// 테스트 케이스 수
int testCnt = sc.nextInt();
while (testCnt-- > 0) {
// 스티커 길이
int N = sc.nextInt();
int[][] D = new int[N+1][3];
// 스티커 점수 0-> 안뜯, 1 -> 위, 2 -> 아래
int[][] A = new int[N+1][3];
for (int j = 1; j < 3; j++) {
for (int i = 1; i <= N; i++) {
A[i][j] = sc.nextInt();
}
}
D[1][0] = 0;
// 길이가 1인데 위 스티커를 뜯은 경우
D[1][1] = A[1][1];
// 길이가 1인데 아래 스티커를 뜯은 경우
D[1][2] = A[1][2];
for (int i = 2; i <= N; i++) {
int nonSelMaxVal = Integer.MIN_VALUE;
int upSelMaxVal = 0;
int downSelMaxVal = 0;
// 뜯지 않는 경우
for (int j = 0; j < 3; j++) {
if (D[i-1][j] > nonSelMaxVal) {
nonSelMaxVal = D[i-1][j];
}
}
// 위쪽 스티커 뜯은 경우
if (D[i-1][0] >= D[i-1][2]) {
upSelMaxVal = D[i-1][0];
} else {
upSelMaxVal = D[i-1][2];
}
// 아래쪽 스티커 뜯은 경우
if (D[i-1][0] >= D[i-1][1]) {
downSelMaxVal = D[i-1][0];
} else {
downSelMaxVal = D[i-1][1];
}
D[i][0] = nonSelMaxVal;
D[i][1] = upSelMaxVal + A[i][1];
D[i][2] = downSelMaxVal + A[i][2];
}
int maxVal = Integer.MIN_VALUE;
for (int j = 0; j < 3; j++) {
// 3 케이스 중에 큰 값을 출력
if (D[N][j] > maxVal) {
maxVal = D[N][j];
}
}
System.out.println(maxVal);
}
}
}
D[i][j] => 2i에서 얻을 수 있는 최대 점수, i번 열에서 뜯는 스티커는 j
j = 0 => 스티커 안뜯음
j = 1 => 위쪽 스티커 뜯음
j = 2 => 아래쪽 스티커 뜯음
D[i][0] => i-1열에서 스티커를 어떻게 뜯었는지 상관 X
D[i][0] = max(D[i-1][0], D[i-1][1], D[i-1][2])
D[i][1] => i-1열에서 스티커를 안뜯거나, 아래 스티커를 뜯어야 함.
D[i][1] = max(D[i-1][0], D[i-1][2]) + A[i][1]
D[i][2] => i-1열에서 스티커를 안뜯거나, 위쪽 스티커를 뜯어야 함.
D[i][2] = max(D[i-1][0], D[i-1][1]) + A[i][2]
위 점화식으로 해결.
- Total
- Today
- Yesterday
- 필터
- 프로그래머스
- Asynchronous
- 비동기
- blocking
- 블로킹
- Handler Interceptor
- 인터셉터
- 프로그래머스 Level 1
- 해시
- 동기
- Synchronous
- 프로그래머스 Level 3
- 핸들러 인터셉터
- non-blocking
- Filter
- a
- 코딩테스트 고득점 Kit
- 스택/큐
- 논블로킹
- 프로그래머스 Level 2
- http://www.nextree.co.kr/p6960/
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |