티스토리 뷰
문제 설명
N개의 스티커가 원형으로 연결되어 있습니다. 다음 그림은 N = 8인 경우의 예시입니다.
원형으로 연결된 스티커에서 몇 장의 스티커를 뜯어내어 뜯어낸 스티커에 적힌 숫자의 합이 최대가 되도록 하고 싶습니다. 단 스티커 한 장을 뜯어내면 양쪽으로 인접해있는 스티커는 찢어져서 사용할 수 없게 됩니다.
예를 들어 위 그림에서 14가 적힌 스티커를 뜯으면 인접해있는 10, 6이 적힌 스티커는 사용할 수 없습니다. 스티커에 적힌 숫자가 배열 형태로 주어질 때, 스티커를 뜯어내어 얻을 수 있는 숫자의 합의 최댓값을 return 하는 solution 함수를 완성해 주세요. 원형의 스티커 모양을 위해 배열의 첫 번째 원소와 마지막 원소가 서로 연결되어 있다고 간주합니다.
제한 사항
- sticker는 원형으로 연결된 스티커의 각 칸에 적힌 숫자가 순서대로 들어있는 배열로, 길이(N)는 1 이상 100,000 이하입니다.
- sticker의 각 원소는 스티커의 각 칸에 적힌 숫자이며, 각 칸에 적힌 숫자는 1 이상 100 이하의 자연수입니다.
- 원형의 스티커 모양을 위해 sticker 배열의 첫 번째 원소와 마지막 원소가 서로 연결되어있다고 간주합니다.
입출력 예
sticker | answer |
---|---|
[14, 6, 5, 11, 3, 9, 2, 10] | 36 |
[1, 3, 2, 5, 4] | 8 |
입출력 예 설명
입출력 예 #1
6, 11, 9, 10이 적힌 스티커를 떼어 냈을 때 36으로 최대가 됩니다.
입출력 예 #2
3, 5가 적힌 스티커를 떼어 냈을 때 8로 최대가 됩니다.
문제 풀이 방법
처음에 이 문제를 접했을 때 짝수, 홀수 인덱스 값들을 전부 더하는 방식으로 풀었는데 이건 옳은 방법이 아니라는 것을 알았다.
이 문제 또한 DP 방법으로 문제를 풀이 해야한다.
이 문제는 두가지 경우를 생각해서 풀이 해야한다.
첫번째 스티커를 선택했을 때와 첫번째 스티커를 선택하지 않고 두번째 스티커부터 선택했을때 두가지를 구한 다음 최댓값을 구하면 된다.
우선 첫번째 스티커를 선택 했을 때를 보자.
첫번째 스티커를 선택 했을 때 첫번째 값은 그대로 14가 되며, 2번째 스티커는 선택이 불가하므로 이전 값인 14가 된다.
3번째 스티커를 사용할때 바로 앞에 있는 스티커는 사용이 불가하므로 -2 위치인 1번 위치의 스티커와 현재 위치의 값을 더한다.
여기서 현재 위치 값을 사용하지 않으면 바로 앞에 스티커를 사용 할수 있으므로 앞에 값과 비교하여 큰 값을 선택 한다.
이것을 배열 끝까지 반복하면 된다.
단 첫번째 스티커를 선택했으니 마지막 스티커 선택이 불가하다.
따라서 첫번째 스티커를 선택 했을 때의 최댓값은 34가 된다.
이제 두번째 스티커 선택 했을 경우를 보자.
두번째 스티커를 선택 했을때는 첫번째 스티커를 선택 못하니 첫번째 값은 0이 되고, 두번째 값은 6이 된다.
3번째 스티커를 사용할때 바로 앞에 있는 스티커는 사용이 불가하므로 -2 위치인 1번 위치의 스티커와 현재 위치의 값을 더한다.
여기서 현재 위치 값을 사용하지 않으면 바로 앞에 스티커를 사용 할수 있으므로 앞에 값과 비교하여 큰 값을 선택 한다.
두번째 스티커를 선택 했을 때는 마지막 인덱스 값을 선택이 가능하니 끝까지 반복하여 진행 한다. 이때 최댓값은 36이 된다.
첫번째 스티커를 선택 했을 때 34, 두번째 스티커를 선택했을 때 36이 되며 이중 큰 값은 두번째 스티커를 선택 했을 때인 36이 된다.
이것을 코드로 표현하면 dp[i] = Math.max(dp1[i - 1],dp1[i - 2] + sticker[i])
이 된다.
전체 코드
class Solution {
public int solution(int sticker[]) {
if (sticker.length == 1) {
return sticker[0];
}
int[] dp1 = new int[sticker.length];
int[] dp2 = new int[sticker.length];
dp1[0] = sticker[0];
dp1[1] = sticker[0];
for (int i = 2; i < sticker.length - 1;i++) {
dp1[i] = Math.max(dp1[i - 1],dp1[i - 2] + sticker[i]);
}
dp2[0] = 0;
dp2[1] = sticker[1];
for (int i = 2; i < sticker.length; i++) {
dp2[i] = Math.max(dp2[i - 1],dp2[i - 2] + sticker[i]);
}
return Math.max(dp1[sticker.length - 2],dp2[sticker.length - 1]);
}
}
'Algorithm > 프로그래머스' 카테고리의 다른 글
프로그래머스 - 큰 수 만들기(Java, 자바) (0) | 2023.08.11 |
---|---|
프로그래머스 - 폰켓몬(Java, 자바) (0) | 2023.08.10 |
프로그래머스 - 등굣길(Java, 자바) (0) | 2023.08.08 |
프로그래머스 - 정수 삼각형(Java, 자바) (0) | 2023.08.07 |
프로그래머스 - 더 맵게 (Java, 자바) (0) | 2023.08.06 |
- Total
- Today
- Yesterday
- 주니어 개발자 취업 준비
- 코딩테스트 준비
- 코딩테스트
- java
- 제로베이스 백엔드 스쿨
- 제로베이스 백준 장학금
- 코테준비
- 알고리즘
- 코테공부
- 취업 준비
- 개발자 취준
- 취준
- 자바
- 코딩테스트공부
- 프로그래머스 자바
- 백엔드 개발자 취업 준비
- 프로그래머스 카카오
- 자바공부
- 개발자 취업 준비
- 기술 면접 준비
- 알고리즘공부
- 프로그래머스
- 취업준비
- 코테 준비
- 코딩테스트 공부
- 알고리즘 공부
- 백엔드 개발자 기술 면접 준비
- 백준
- 백엔드 개발자
- 개발자 면접 준비
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |