Tiny Bunny
본문 바로가기

programmers

프로그래머스 3단계 : 스티커 모으기(2) (Java 자바)

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