
2n 개의 스티커가 있고 스티커는 n개씩 2줄로 배치되어 있다.
스티커 한장을 뜯으면 해당 스티커 상하좌우로 있는 스티커는 못쓴다.
예를 들어 아래와 같이 n은 2인 스티커가 있다고 했을 때,
| n = 1 | n = 2 |
|---|---|
| O | O |
| O | O |
0,0 위치의 스티커를 뜯으면 다음과 같이 된다.
| n = 1 | n = 2 |
|---|---|
| 뜯음 | X |
| X | O |
위의 조건에서 스티커마다 점수가 있을 때, 점수의 합이 최대가 되도록 스티커를 뜯으면 몇점인가?
이 문제에서 입력으로 스티커의 점수가 2차원 배열로 주어진다.
2차원 배열의 왼쪽부터 차례대로 각각의 스티커를 뜯을 경우의 최댓값을 알고 싶다.
첫번쨰의 경우 (i = 1) 당연히 자기 자신을 뽑는 경우가 최댓값이다.
| i = 1 | i = 2 | i = 3 |
|---|---|---|
| A | B | E |
| B | A | F |
두번쨰의 경우 (i = 2) 아래와 같은 경우 C를 뜯을 최댓값은 B와 C를 뜯는 것이다.
그와 반대로 D를 뜯는 최댓값은 A + D가 될 것이다.
| i = 1 | i = 2 | i = 3 |
|---|---|---|
| A | B + C | E |
| B | A + D | F |
세번쨰의 경우 (i = 3)
E의 위치에 오는 최댓값은 2가지를 확인해야 한다.
Math.max( A + D, B )
| i = 1 | i = 2 | i = 3 |
|---|---|---|
| A | B + C | Math.max( A + D, B ) + E |
| B | A + D | Math.max( B + C, A ) + F |
전체 풀이
let fs = require("fs");
let input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
const TestCase = parseInt(input.shift());
const FindMax = () => {
let N = input.shift();
let Stickers = input.splice(0, 2).map(v => v.split(' ').map(Number));
// 스티커가 모두 2장일 경우를 위해 초기값 설정.
let max = Math.max(Stickers[0][0], Stickers[1][0]);
for (let i = 1; i < parseInt(N); i++) {
for (let j = 0; j < 2; j++) {
const CompareJ = j === 0 ? 1 : 0;
// i - 2가 있을 경우에만.
if (i >= 2 && Stickers[j][i - 2] !== undefined) {
Stickers[j][i] = Math.max(Stickers[CompareJ][i - 1],Stickers[CompareJ][i - 2]) + Stickers[j][i];
max = Stickers[j][i] > max ? Stickers[j][i] : max;
} else {
Stickers[j][i] = Stickers[CompareJ][i - 1] + Stickers[j][i];
max = Stickers[j][i] > max ? Stickers[j][i] : max;
}
}
}
return max;
};
const solution = () => {
let answer = [];
for (let i = 0; i < TestCase; i++) {
answer.push(FindMax());
}
console.log(answer.join('\n'));
};
solution();
처음에 i - 2 가 없을 때를 위한 조건문을 if (Stickers[j][i - 2])라고만 설정했더니 틀렸다고 계속 나와서 30분가량 헤맸다.
문제의 조건을 보면 점수는 0점부터 100점까지 있을 수 있기 때문에 조건문을 저렇게 설정을 하게 되면 점수가 0점일 경우 false가 되기 때문에 당연히 오류가 발생하게 된다.
문제의 조건을 유의하여 코드 작성을 진행해야겠다.