풀이과정
첫번째 접근 : 2차원 배열로 모든 경우의 수 때려넣기
다이나믹 프로그래밍이라 하면 주어진 문제 해결을 위해 여러 개의 하위 문제로 나누어 푸는 방법을 말한다. 부분 문제가 다른 문제들을 해결하는데 사용될 수 있어 답을 여러 번 계산하는 대신 한 번만 계산하고 그 결과를 재활용하는 메모제이션 기법으로 속도를 향상시킨다.
근데 나는 다 구해버렸다…
dp[i][j]
가 i번째 원소부터 j번째 원소까지의 합이 되도록 모든 값들을 구하고, 각 행에서 최대값을 maxArr
에 넣어 그 중 최대값을 반환하도록 구현했다. 풀면서도 안되겠구나 생각은 했지만, 내가 원하는 방식으로 구현하는 연습을 하기 위해 그냥 끝까지 구현은 했다.
결과는 메모리 초과…
// 2차원 배열로 각 원소의 행 i, 열 j 값은 i부터 j까지의 합이 되도록 dp배열 구현
const dp = [...Array(N)].map(v => [...Array(N)].map(v => -1000 * N));
for (let i = 0; i < N; i++) {
dp[i][i] = nums[i];
}
for (let i = 0; i < N; i++) {
for (let j = i + 1; j < N; j++) {
if (j - 1 >= 0) dp[i][j] = dp[i][j - 1] + dp[j][j];
}
}
// 각 행별로 최대값을 배열에 담아 그 중 최대 값을 반환
const maxArr = [];
for (let i = 0; i < N; i++) {
const max = Math.max(...dp[i]);
maxArr.push(max);
}
console.log(Math.max(...maxArr));
두번째 접근
가장 간단한 부분해 찾기
그 부분해로부터 다른 문제의 해를 찾기
결국 다이나믹 프로그래밍으로 문제를 풀기 위해서는 이차원 배열이 아닌 일차원으로 만들어야 한다고 생각을 했고, 주어진 입력값 중 nums[N-1]
이 dp[N-1]
이 됨을 생각해 낼 수 있었다.
dp[N-1]
이 결정되자, dp[N-2] = Math.max(nums[N-2], nums[N-2]+dp[N-1]
의 방식으로 점화식을 세울수도 있었고 쉽게 문제를 해결할 수 있었다.
정답코드
const filePath = process.platform === 'linux' ? 'dev/stdin' : './input.txt';
const input = require('fs').readFileSync(filePath).toString().split('\n');
const n = Number(input.shift());
const nums = input
.shift()
.split(' ')
.map(v => Number(v));
const dp = [...Array(n)].map(v => 0);
dp[n - 1] = nums[n - 1];
for (let i = n - 2; i >= 0; i--) {
dp[i] = Math.max(nums[i], nums[i] + dp[i + 1]);
}
console.log(Math.max(...dp));
'알고리즘 문제풀이' 카테고리의 다른 글
프로그래머스 - 부대 복귀(Javascript) (0) | 2023.11.29 |
---|---|
백준 - 1406 에디터 (1) | 2023.11.24 |
백준 silver 3 - 1463 1로 만들기(Javascript) (0) | 2023.11.20 |
백준 silver 4 - 2839 설탕 배달(Javascript) (1) | 2023.11.20 |
프로그래머스 level 2 - 숫자 변환하기(Javascript) (0) | 2023.11.15 |