| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- 프로그래머스 봉인된 주문
- BFS
- 컴퓨터네트워크
- 비동기함수
- C++
- react-quill
- 프로그래머스 택배 상자 꺼내기
- 프로그래머스 완전범죄
- 프로그래머스 호텔 방 배정
- react상태관리라이브러리
- zustand
- 프로그래머스 충돌 위험 찾기
- 프로그래머스 사칙연산
- 서버증설횟수
- 프로그래머스 비밀 암호 해독
- 프로그래머스 지게차와 크레인
- 리렌더링최적화
- 최소힙우선순위큐
- git
- 충돌 위험 찾기
- 프로그래머스 석유 시추
- 다익스트라 Js
- react hook
- react-router-dom
- CSS
- 프로그래머스 1843
- 프로그래머스 퍼즐 게임 챌린지
- 비밀 암호 해독
- JS우선순위큐
- 프로그래머스 숫자 타자 대회
- Today
- Total
leebaek
[프로그래머스 Lv4] 사칙연산 - Javascript 풀이 본문
https://school.programmers.co.kr/learn/courses/30/lessons/1843
프로그래머스
SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제
정수와 +, - 연산자가 번갈아 들어 있는 배열이 주어졌을 때,
괄호를 적절히 배치하여 만들 수 있는 계산 결과 중 최댓값을 구하는 문제
생각
단순히 왼쪽부터 순차 계산하면 괄호의 효과를 전혀 반영할 수 없다.
특히 − 연산은 결합법칙이 성립하지 않기 때문에
중간에 어떤 값을 먼저 계산하느냐에 따라 결과가 크게 달라진다.
그래서 구간별로 만들 수 있는 최댓값과 최솟값을 모두 관리하는 DP가 필요하다고 생각했다.
문제풀이
테이블을 정의해보자.
Max[i][j] : i번째 숫자부터 j번째 숫자까지 계산해서 얻을 수 있는 최댓값
Min[i][j] : i번째 숫자부터 j번째 숫자까지 계산해서 얻을 수 있는 최솟값
여기서 i, j는 숫자의 인덱스이다.
연산자는 숫자 사이에 하나씩 존재하므로,
연산자 op[k]는 num[k] 와 num[k+1] 사이에 위치한다.
구간의 길이가 1이라면,
단순히 해당 숫자 하나이므로
Max[i][i] = Min[i][i] = num[i]
현재 구간이 i부터 j라면,
모든 k (i ≤ k < j)에 대해 연산자 op[k]를 기준으로 왼쪽/오른쪽 구간을 나눌 수 있다.
이때 op[k]가 +인지 -인지에 따라 계산값이 달라지므로
왼쪽/오른쪽 구간의 최댓값/최솟값 조합을 모두 고려해야 한다.
점화식은 다음과 같다.
왼쪽: i ~ k
오른쪽: k+1 ~ j
가능한 조합은 총 네 가지:
Max[i][k] op Max[k+1][j]
Max[i][k] op Min[k+1][j]
Min[i][k] op Max[k+1][j]
Min[i][k] op Min[k+1][j]
이 모든 값 중 최댓값 → Max[i][j]
모든 값 중 최솟값 → Min[i][j]
이렇게 결정한다.
시간복잡도는 구간 DP의 전형적인 구조라
O(N³)이다.
코드
function solution(arr) {
const nums = [];
const ops = [];
// 숫자와 연산자 분리
for (let i = 0; i < arr.length; i++) {
if (i % 2 === 0) nums.push(Number(arr[i]));
else ops.push(arr[i]);
}
const n = nums.length;
// DP 테이블 초기화
const Max = Array.from({ length: n }, () => Array(n).fill(-Infinity));
const Min = Array.from({ length: n }, () => Array(n).fill(Infinity));
// 길이 1 구간 초기화
for (let i = 0; i < n; i++) {
Max[i][i] = nums[i];
Min[i][i] = nums[i];
}
// a op b 계산 함수
function calc(a, b, op) {
return op === '+' ? a + b : a - b;
}
// 구간 길이 len = 2 ~ n
for (let len = 2; len <= n; len++) {
for (let i = 0; i + len - 1 < n; i++) {
const j = i + len - 1;
for (let k = i; k < j; k++) {
const op = ops[k];
const candidates = [
calc(Max[i][k], Max[k+1][j], op),
calc(Max[i][k], Min[k+1][j], op),
calc(Min[i][k], Max[k+1][j], op),
calc(Min[i][k], Min[k+1][j], op),
];
Max[i][j] = Math.max(Max[i][j], ...candidates);
Min[i][j] = Math.min(Min[i][j], ...candidates);
}
}
}
return Max[0][n-1];
}
'PS > 프로그래머스_PS' 카테고리의 다른 글
| [프로그래머스 Lv4] 징검다리 - Javascript 풀이 (0) | 2025.11.25 |
|---|---|
| [프로그래머스 Lv4] 도둑질 - Javascript 풀이 (0) | 2025.11.24 |
| [프로그래머스 Lv3] 정수 삼각형 - Javascript 풀이 (0) | 2025.11.20 |
| [프로그래머스 Lv3] 숫자 타자 대회 - Javascript 풀이 (0) | 2025.11.19 |
| [프로그래머스 Lv3] 합승 택시 요금 - Javascript 풀이 (0) | 2025.11.18 |