상상쓰

[프로그래머스] 매출 하락 최소화 본문

Coding Test

[프로그래머스] 매출 하락 최소화

상상쓰 2021. 8. 10. 17:45

https://programmers.co.kr/learn/courses/30/lessons/72416

 

코딩테스트 연습 - 매출 하락 최소화

CEO를 포함하여 모든 직원은 팀장 또는 팀원이라는 직위를 가지고 있으며 그림에서는 팀장과 팀원의 관계를 화살표로 표시하고 있습니다. 화살표가 시작되는 쪽의 직원은 팀장, 화살표를 받는

programmers.co.kr

 

DFS 와 동적 계획법을 이용하여 풀 수 있을 거라고는 생각했는데 dp 배열을 구현하기가 어려워서 다른 블로그를 참고하여 풀어나갔다.

 

dp[i][0] : i 가 참석하지 않았을 때의 최솟값, dp[i][1] : i 가 참석했을 때 최솟값으로 정의하고,

기본값으로 dp[i][1] = sales[i-1], dp[i][0] = 0 으로 시작한다.

 

리프 노드부터 후위로 순회하여 각 팀의 팀장의 dp[][] 를 채워나가면서 마지막에 도달하는 dp[1][0] 과 dp[1][1] 을 채워 그 중 최솟값을 구하는 것으로 이해하면 되겠다.

 

map.containsKey(leader) == true 이면 list = map.get(leader) 는 leader 를 팀장으로 하는 팀원들이다.

각 팀원이 참석할 때와 참석하지 않을 때를 비교하여 아래 4가지 상황을 만들 수 있다.

 

1) 팀장이 불참, 팀원이 불참

2) 팀장이 참석, 팀원이 불참

3) 팀장이 불참, 팀원이 참석

4) 팀장이 참석, 팀원이 참석

 

1), 2) 는 팀원이 불참할 때 최솟값을 가지는 경우이며 3), 4) 는 참석할 때 최솟값을 가지는 경우이다.

또한, 1) 의 경우 각 팀에서 한 명 이상이 참석해야 한다는 조건을 만족하기 위해 temp 라는 변수를 만들어 다른 팀원이 참석할 경우의 최솟값을 temp 에 담는다. 

temp = Math.min(temp, dp[팀원][1] - dp[팀원][0]) 이미 dp[leader][0] += dp[팀원][0] 이 되었기 때문에 temp 에는 dp[팀원][1] - dp[팀원][0] 을 담는다. 3), 4) 의 경우, 앞의 조건을 만족하는 경우이므로 temp 를 0 으로 한다.

 

결과적으로, CEO인 1번의 dp 가 채워지면 dp[1][0], dp[1][1](= 1번이 참석하지 않을 때, 참석할 때) 중 최솟값을 반환해준다. 

 

import java.util.*;

class Solution {
    
    public static void rf(int leader, HashMap<Integer, List<Integer>> map, int[] sales, int[][] dp) {
        dp[leader][1] = sales[leader-1];
        int temp = 10000;
        
        if (map.containsKey(leader)) {
            List<Integer> list = map.get(leader);
            
            for (int i : list) {   
                rf(i, map, sales, dp);
                
                if (dp[i][0] < dp[i][1]) {
                    dp[leader][0] += dp[i][0];
                    dp[leader][1] += dp[i][0];
                    temp = Math.min(dp[i][1] - dp[i][0], temp);
                } else {
                    dp[leader][0] += dp[i][1];
                    dp[leader][1] += dp[i][1];
                    temp = 0;
                }
            }
            
            dp[leader][0] += temp;
        }
    }
    
    public static int solution(int[] sales, int[][] links) {
        int answer = 0;
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        int[][] dp = new int[sales.length+1][2];
        
        for (int i=0;i<links.length;i++) {
            if (map.containsKey(links[i][0])) {
                map.get(links[i][0]).add(links[i][1]);
            } else {
                List<Integer> list = new ArrayList<>();
                list.add(links[i][1]);
                map.put(links[i][0], list);
            }
        }
        
        rf(1, map, sales, dp);
        answer = Math.min(dp[1][0], dp[1][1]); 
        
        return answer;
    }
}

'Coding Test' 카테고리의 다른 글

[백준] 돌 게임  (0) 2021.08.12
[백준] 평범한 배낭  (0) 2021.08.11
[프로그래머스] 2주차_상호평가  (0) 2021.08.09
[프로그래머스] 멀리 뛰기  (0) 2021.08.09
[백준] LCS  (0) 2021.08.07
Comments