Algorithm
[Algo] 프로그래머스 스티커 모으기(2)
조핑구
2024. 5. 9. 10:29
import java.util.*;
class Solution {
public int solution(int sticker[]) {
int len=sticker.length;
int[]frist=new int[len+1];
int[]second=new int[len+1];
if(len==1){
return sticker[0];
}
int[]tmp=Arrays.copyOf(sticker,len);
tmp[len-1]=0;
frist[0]=tmp[0];
frist[1]=Math.max(frist[0],tmp[1]);
for(int i=0; i<len-2; i++){
frist[i+2]=Math.max(frist[i+1], frist[i]+tmp[i+2]);
}
for(int i=0; i<len-1; i++){
tmp[i]=sticker[i+1];
}
tmp[len-1]=0;
second[0]=tmp[0];
second[1]=Math.max(second[0],tmp[1]);
for(int i=0; i<len-2; i++){
second[i+2]=Math.max(second[i+1], second[i]+tmp[i+2]);
}
return Math.max(frist[len-1],second[len-1]);
}
}
문제는 일차원 배열의 처음과 끝을 연결해 원형을 만들었음을 명시했지만, 맨 처음과 끝의 스티커를 관리하는 로직을 따로 추가해준다면 직선과 같이 풀 수 있다. 현재값(i)에서 가질 수 있는 가장 큰 값은
- 전칸에서 스티커를 뽑아서 현재 칸은 뽑을 수 없는 경우
- 전칸에서 스티커를 뽑지 않아서 현재 칸을 뽑을 수 있는 경우, 2전칸+현재칸을 뽑았다.
를 비교하면 알 수 있다.
식으로 쓴다면
- dp[i]=dp[i-1]
- dp[i]=dp[i-2]+sticker[i]
이다.
1번 스티커를 뽑는다면 마지막 스티커를 쓸 수 없고, 1번 스티커를 뽑지 않는다면 마지막 스티커를 사용할 수 있다. 1번 스티커의 유무는 배열의 값이 달라지는 결과를 낳기 때문에 따로 dp를 만들어주었다.
따라서 위의 두 가지 경우 * 스티커의 시작점 두 가지를 모두 DP로 계산해주면 된다!