From 61974401a0a2f6c3ae0ed40f8c6afd549ce5711e Mon Sep 17 00:00:00 2001 From: yoouyeon Date: Sat, 7 Feb 2026 18:43:58 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A1=20=ED=94=84=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=EB=A8=B8=EC=8A=A4=2072416=20-=20=EB=A7=A4=EC=B6=9C=20?= =?UTF-8?q?=ED=95=98=EB=9D=BD=20=EC=B5=9C=EC=86=8C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...5_\354\265\234\354\206\214\355\231\224.js" | 75 +++++++++++++++++++ Programmers/README.md | 1 + 2 files changed, 76 insertions(+) create mode 100644 "Programmers/Level4/72416_\353\247\244\354\266\234_\355\225\230\353\235\275_\354\265\234\354\206\214\355\231\224.js" diff --git "a/Programmers/Level4/72416_\353\247\244\354\266\234_\355\225\230\353\235\275_\354\265\234\354\206\214\355\231\224.js" "b/Programmers/Level4/72416_\353\247\244\354\266\234_\355\225\230\353\235\275_\354\265\234\354\206\214\355\231\224.js" new file mode 100644 index 0000000..f189888 --- /dev/null +++ "b/Programmers/Level4/72416_\353\247\244\354\266\234_\355\225\230\353\235\275_\354\265\234\354\206\214\355\231\224.js" @@ -0,0 +1,75 @@ +/* +⭐️ 문제 정보 ⭐️ +문제 : 72416 - 매출 하락 최소화 +레벨 : Level 4 +링크 : https://school.programmers.co.kr/learn/courses/30/lessons/72416 +*/ + +// ANCHOR : 26.02.07 풀이 +function solution(sales, links) { + const n = sales.length; + + // 1) 인접 리스트 구성 + const children = Array.from({ length: n + 1 }, () => []); + for (const [a, b] of links) { + children[a].push(b); + } + + // 2) 후위순회 준비 + // NOTE: order를 역순으로 처리해서 postorder 효과를 낸다. + const order = []; + const stack = [1]; + while (stack.length) { + const v = stack.pop(); + order.push(v); + for (const c of children[v]) { + stack.push(c); + } + } + + // 3) dp 배열 준비 (1-indexed) + // dp0: v가 참석했을 때의 워크숍 참석 인원의 총 하루 평균 매출액 최솟값 + // dp1: v가 참석하지 않았을 때의 워크숍 참석 인원의 총 하루 평균 매출액 최솟값 + const dp0 = new Array(n + 1).fill(0); + const dp1 = new Array(n + 1).fill(0); + + // 4) Bottom-up DP 계산 (order를 역순으로 돌면서 후위순회) + for (let i = order.length - 1; i >= 0; i--) { + const v = order[i]; + const childs = children[v]; + + // case 1) 리프인 경우 (순수 팀원인 경우) + // - dp0[v] = sales[v] (본인이 참석) + // - dp1[v] = 0 (본인 불참. 아래 팀이 없기 때문에 자식 중 한명이 꼭 참석해야 한다는 강제가 없다. 불참하면 끝.) + if (childs.length === 0) { + dp1[v] = sales[v - 1]; + dp0[v] = 0; + continue; + } + + // case 2) 팀장이고 팀원인 경우 (하위 팀이 있음) + // a) 참석하는 경우 : 같은 팀의 다른 팀원들은 참석하든 안하든 상관 없음 + // -> dp1[v] = sales[v] + ∑ min(dp0, dp1) + // b) 불참하는 경우 : 같은 팀의 다른 팀원 중 적어도 한명은 참석해야 함 + // -> 우선 모든 팀원들에서 가장 싼 상태를 더한 뒤 (sumMin) + // -> 참석으로 돌렸을 때 비용이 가장 적게 추가되는 인원을 참석으로 돌린다. (extraMin) + // -> dp0[v] = sumMin + extraMin + let sumMin = 0; + let extraMin = Infinity; + + for (const c of childs) { + const m = Math.min(dp0[c], dp1[c]); // 참석하는 것과 안하는 것 중 최솟값 + sumMin += m; + + const extra = dp1[c] - m; // (참석으로 돌렸을 때 추가되는 비용) + if (extra < extraMin) { + extraMin = extra; + } + } + + dp1[v] = sales[v - 1] + sumMin; + dp0[v] = sumMin + extraMin; + } + + return Math.min(dp0[1], dp1[1]); +} diff --git a/Programmers/README.md b/Programmers/README.md index 5c7180a..08cad22 100644 --- a/Programmers/README.md +++ b/Programmers/README.md @@ -60,6 +60,7 @@ | 68936 | 쿼드압축 후 개수 세기 | [68936_쿼드압축_후_개수_세기.js](Level2/68936_쿼드압축_후_개수_세기.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/68936) | | 70129 | 이진 변환 반복하기 | [70129_이진_변환_반복하기.js](Level2/70129_이진_변환_반복하기.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/70129) | | 72411 | 메뉴 리뉴얼 | [72411_메뉴_리뉴얼.js](Level2/72411_메뉴_리뉴얼.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/72411) | +| 72416 | 매출 하락 최소화 | [72416_매출_하락_최소화.js](Level4/72416_매출_하락_최소화.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/72416) | | 76502 | 괄호 회전하기 | [76502_괄호_회전하기.js](Level2/76502_괄호_회전하기.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/76502) | | 77484 | 로또의 최고 순위와 최저 순위 | [77484_로또의_최고_순위와_최저_순위.js](Level1/77484_로또의_최고_순위와_최저_순위.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/77484) | | 77486 | 다단계 칫솔 판매 | [77486_다단계_칫솔_판매.js](Level3/77486_다단계_칫솔_판매.js) | [🔗](https://school.programmers.co.kr/learn/courses/30/lessons/77486) |