일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Today
- Total
- 스프링 싱글톤
- HandlerMethodArgumentResolver
- Spring interceptor
- 라즈베리파이
- RequiredArgsConstructor
- qualifier
- 스프링 컨테이너
- 스프링 Configuration
- DI
- UsernamePasswordAuthenticationFilter
- springsecurity
- ComponentScan
- 빈 중복 오류
- Spring
- beandefinition
- 라즈베리파이4
- 스프링 빈
- 스프링
- 객체지향
- 스프링 빈 조회
- 롬복 Qualifier
- Autowired 옵션
- autowired
- docker
- 생성자 주입
- Servlet Filter
- 싱글톤 컨테이너
- DI컨테이너
- 도커
- 의존관계 주입
그날그날 공부기록
9465 스티커 본문
9465 스티커
문제: https://www.acmicpc.net/problem/9465
문제 이해
완전탐색으로도 정답은 구할 수 있지만, n의 최댓값은 100,000이므로 시간제한에 걸리게 된다.
DP로 풀기 위해 점화식을 찾아보자.
떼어낸 스티커의 상하좌우에 있는 스티커는 사용할 수 없다.
우선 간단히 생각해보면 다음 그림과 같이 대각선을 반복하는 2가지의 경우가 나온다.
이 두 가지의 경우에서 최댓값은 250이지만, 이는 전체 경우의 수에서 최댓값이 아니다.
스티커를 선택하지 않는 경우가 있기 때문이다.
다음 그림처럼 100 다음 열인 3열의 스티커를 선택하지 않는다면, 60인 스티커를 선택할 수 있어 260으로 최댓값을 구할 수 있다.
100 다음 한 열을 건너뛰고 40을 선택하는 경우는 항상 최댓값을 구할 수 없다.
10을 선택해도 40을 고를 수 있기 때문이다.
따라서 한 열을 건너뛰려면 대각선에 있는 스티커를 골라야 한다.
그렇다면 두 개의 열을 건너뛰는 경우는 어떨까?
[1][1]에 있는 50 스티커를 선택한 뒤 두 개의 열을 건너뛰고, [0][4]의 스티커를 선택한다고 생각해 보자.
이렇게 두개의 열을 건너뛰는 경우 역시 항상 최댓값이 나오지 않는다.
[][4] 이전의 스티커인 [][2] or [][3]을 선택해도 [][4]를 선택할 수 있기 때문에, [][4] 이전의 스티커를 챙기는 게 항상 값이 크기 때문이다.
따라서 스티커 한 열을 건너뛰는 경우만 고려하면 된다.
다음 사진처럼 [1][4]에 있는 스티커 60을 선택하는 경우는 두 가지이다.
- [0][2]의 스티커 100을 선택하고 바로 [1][4]를 선택하는 경우
- [0][3]의 스티커 20을 선택하고 [1][4]를 선택하는 경우
만약 [0][4]의 스티커 40을 선택하는 경우는 이 반대인 [1][2], [1][3]을 고려하면 될 것이다.
val[][] 배열을 현재 스티커까지의 최대 점수 합이라고 생각하면 다음과 같은 식을 도출할 수 있다.
→ val[1][4] = MAX( val[0][3], val[0][2] ) + sticker[1][4]
다른 스티커 역시 이와 같은 경우를 고려하면 된다.
따라서 점화식은 다음과 같다
val[row][col] = MAX( val[다른 row][col-1], val[다른 row][col-2] ) + sticker[row][col]
코드
stickers는 각 스티커의 가치를 저장하고, values는 현재 스티커까지의 최댓값을 저장한다.
계산의 편의를 위해 맨 앞에 아무것도 선택하지 않은 열을 추가했다. (n+1 개 열)
→ col-2를 바로 계산 가능하다.
첫 열의 스티커는 자기 자신이 항상 최댓값이므로 초기화 해주었다.
import java.io.*;
class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int i = 0; i < T; i++) {
int n = Integer.parseInt(br.readLine());
int[][] stickers = new int[2][n+1];
int[][] values = new int[2][n+1];
// stickers 배열 초기화
for (int j = 0; j < 2; j++) {
String[] split = br.readLine().split(" ");
for (int k = 1; k <= n; k++) {
stickers[j][k] = Integer.parseInt(split[k-1]);
}
}
// 첫 열의 스티커 초기화
values[0][1] = stickers[0][1];
values[1][1] = stickers[1][1];
for (int j = 2; j <= n; j++) {
values[0][j] = Math.max(values[1][j-1], values[1][j-2]) + stickers[0][j];
values[1][j] = Math.max(values[0][j-1], values[0][j-2]) + stickers[1][j];
}
System.out.println(Math.max(values[0][n], values[1][n]));
}
}
}
'알고리즘 > 백준 - JAVA' 카테고리의 다른 글
10844 쉬운 계단 수 (0) | 2024.01.02 |
---|---|
2212 센서 (1) | 2023.12.23 |
19598 최소 회의실 개수 (0) | 2023.12.22 |
13164 행복 유치원 (0) | 2023.12.22 |