[문제풀이] 스티커 모으기2

업데이트:

문제 링크 : 스티커 모으기2

풀이 시간 : 60분

1. 문제 풀이

DP를 이용하여 최대 값을 찾는 문제

원형으로 모양이기 때문에 첫 번째를 사용하는 경우와 안하는 경우로 나워서 최대 값을 찾음

1) 첫 번째 스티커를 무조건 사용한 경우에서 최대 값을 찾음

2) 사용하지 않은 경우에서 최대 값을 찾음

3) 두 경우의 최대 값을 찾음

2. 소스 코드

    public int solution(int sticker[]) {
		int answer = 0;
		// 각 스티커를 사용할 지, 사용했을 때 값은 0번, 사용하지 않았을 때 1번에 인덱스에 저장
		int[][] arr = new int[sticker.length][2];
		if (sticker.length > 2) {//sticker 길이가 1일때 조심 33번 테케
			// 무조건 첫번째를 사용할 때
			arr[1][0] = sticker[0];// 첫번째를 사용하면 두번째를 사용하지 못하기 때문에
			arr[1][1] = sticker[0];
			for (int i = 2; i < arr.length - 1; i++) {
				// 현재 스티커를 사용하면 이전 스티커가 사용하지 않아야기 때문에
				// 이전 스티커를 사용하지 않는 비용인 arr[i-1][1]와 현재 스티커 비용을 더함
				arr[i][0] = arr[i - 1][1] + sticker[i];
				// 사용하지 않을 경우 이전 스티커에서 최대 값을 저장
				arr[i][1] = Math.max(arr[i - 1][0], arr[i - 1][1]);
			}
			//첫번째를 무조건 사용하였기 때문에 마지막 스티커도 사용 불가능
			//그래서 마지막 스티커 전 스티커에서 최대값을 뽑음
			answer = Math.max(arr[arr.length - 2][0], arr[arr.length - 2][1]);
			//첫 번째를 사용 안 할 때
			arr[1][0] = sticker[1];
			arr[1][1] = 0;
			for (int i = 2; i < arr.length; i++) {
				arr[i][0] = arr[i - 1][1] + sticker[i];
				arr[i][1] = Math.max(arr[i - 1][0], arr[i - 1][1]);
			}
			// 첫번째를 사용 안하기 때문에 마지막 스티커에서 최대값 선택
			answer = Math.max(answer, Math.max(arr[arr.length - 1][0], arr[arr.length - 1][1]));
		}else {
			answer = sticker[0];
		}
		return answer;
	}

3. 후기

원형이라서 첫 번째의 경우를 처리하는 방법이 떠오르지 않아서

사용할 때와 사용하지 않는 경우를 나눠서 두 가지의 경우를 다 돌렸다

나중에 시간이 되면 한 번에 처리하는 경우를 생각할 예정이다

아래 주의를 생각하지 못해서 시간이 오래걸렸다.

4. 주의

스트커의 길이가 1인 경우를 처리하지 않아서 계속 33번이 틀렸다.

길이가 1인 경우 처음 초기 값 세팅을 할 때 인덱스의 범위를 벗어나서 계속 틀렸다고 나온다(33번 케이스)