728x90
문제 설명
N개의 스티커가 원형으로 연결되어 있습니다. 다음 그림은 N = 8인 경우의 예시입니다.
원형으로 연결된 스티커에서 몇 장의 스티커를 뜯어내어 뜯어낸 스티커에 적힌 숫자의 합이 최대가 되도록 하고 싶습니다. 단 스티커 한 장을 뜯어내면 양쪽으로 인접해있는 스티커는 찢어져서 사용할 수 없게 됩니다.
예를 들어 위 그림에서 14가 적힌 스티커를 뜯으면 인접해있는 10, 6이 적힌 스티커는 사용할 수 없습니다. 스티커에 적힌 숫자가 배열 형태로 주어질 때, 스티커를 뜯어내어 얻을 수 있는 숫자의 합의 최댓값을 return 하는 solution 함수를 완성해 주세요. 원형의 스티커 모양을 위해 배열의 첫 번째 원소와 마지막 원소가 서로 연결되어 있다고 간주합니다.
제한 사항
- sticker는 원형으로 연결된 스티커의 각 칸에 적힌 숫자가 순서대로 들어있는 배열로, 길이(N)는 1 이상 100,000 이하입니다.
- sticker의 각 원소는 스티커의 각 칸에 적힌 숫자이며, 각 칸에 적힌 숫자는 1 이상 100 이하의 자연수입니다.
- 원형의 스티커 모양을 위해 sticker 배열의 첫 번째 원소와 마지막 원소가 서로 연결되어있다고 간주합니다.
입출력 예
풀이
원형의 스티커에서 스티커를 뜯어내어 얻을 수 있는 숫자의 합의 최댓값을 찾는 문제입니다.
원형 스티커에서 스티커를 뜯어내어 얻을 수 있는 최대 합을 구하는 동적 계획법(Dynamic Programming) 알고리즘을 사용했습니다. 스티커를 뜯어내는 경우를 두 가지로 나누어 계산하고, 그 중 더 큰 값을 선택하여 최대 합을 구합니다.
class Solution {
public int solution(int sticker[]) {
int answer = 0;
int len = sticker.length;
if (len == 1) return sticker[0]; // 스티커가 하나인 경우 그 하나의 스티커 값이 최대값이 됩니다.
int[] dp1 = new int[len]; // 첫 번째 스티커를 뜯는 경우를 저장할 배열
int[] dp2 = new int[len]; // 두 번째 스티커를 뜯는 경우를 저장할 배열
// 첫 번째 스티커를 뜯는 경우
dp1[0] = sticker[0]; // 첫 번째 스티커 값을 그대로 저장
dp1[1] = sticker[0]; // 첫 번째 스티커를 뜯는 경우 두 번째 스티커를 뜯을 수 없으므로 첫 번째 스티커 값으로 초기화
// 두 번째 스티커를 뜯는 경우
dp2[1] = sticker[1]; // 두 번째 스티커 값을 그대로 저장
// 세 번째 스티커부터 마지막 스티커까지 계산
for (int i = 2; i < len; i++) {
// dp1 배열에는 i번째 스티커를 뜯지 않은 경우와 (i-2)번째까지의 최대 합에 현재 스티커 값을 더한 경우 중 큰 값을 저장
dp1[i] = Math.max(dp1[i-1], dp1[i-2] + sticker[i]);
// dp2 배열에는 i번째 스티커를 뜯지 않은 경우와 (i-2)번째까지의 최대 합에 현재 스티커 값을 더한 경우 중 큰 값을 저장
dp2[i] = Math.max(dp2[i-1], dp2[i-2] + sticker[i]);
}
// 마지막 스티커를 뜯어내는 경우 중 더 큰 값을 최종 결과로 선택
answer = Math.max(dp1[len-2], dp2[len-1]);
return answer; // 최종 최대값 반환
}
}
728x90
'programmers' 카테고리의 다른 글
프로그래머스 3단계 : 징검다리 건너기 (Java 자바) (0) | 2023.09.06 |
---|---|
프로그래머스 3단계 : 불량 사용자 (Java 자바) (0) | 2023.09.06 |
프로그래머스 3단계 : 베스트 앨범 (Java 자바) (0) | 2023.09.06 |
프로그래머스 3단계 : 기지국 설치 (Java 자바) (0) | 2023.09.05 |
프로그래머스 3단계 : 가장 먼 노드 (Java 자바) (0) | 2023.08.31 |