ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 - 매출 하락 최소화
    Problem Solving/Programmers 2021. 8. 7. 17:24

    문제가 넘 어려워서 다른 분의 풀이를 참고하여 이해하였다

     

    접근 과정

     

    트리 dp

     

    1. dp[k][0] - k팀의 팀장이 뽑히는 경우

    2. dp[k][1] - k팀의 팀원이 뽑히는 경우

     

    팀 이름은 팀장의 번호를 따라감

    d[k][0]은 본인의 매출, d[k][1]은 0으로 세팅

     

     

    1. 

    내가 팀장으로 뽑힐 때

    내 팀원이 팀장으로 뽑힐 때, 팀원으로 뽑힐 때 모두 고려해야 함

    d[k][0] += min(d[child][0], d[child][1])

     

    2.

    이 경우 역시 d[child][0], d[child][1] 중 최소값을 전부 더해주면 되지만 두 가지 케이스로 나뉨

     

    i) d[child][0]이 최소인 팀원이 하나라도 있을 때, 땡큐인 상황  1번과 똑같이 진행

    d[k][1] += min(d[child[0], d[child][1])

     

    ii) 모든 child가 d[child][1]이 최소일 때, 어쩔 수 없이 한명이 선택되어야 함

     

    즉, d[k][1] += min(d[child[0], d[child][1])에서 전부 d[child][1]가 더해지는 경우에서

    한 팀원이 선택되어 dp[child][1] 대신 d[child][0]이 더해져야 한다.

     

    이때 d[child][0] - d[child][1]이 가장 작은 팀원을 선택해준다.

     

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include <string>
    #include <vector>
    #define INF 1e18
    using namespace std;
     
    vector<int> v[300001];
     
    // dp[k][0] 팀장이 뽑히는 경우
    // dp[k][1] 팀원이 뽑히는 경우
    long long dp[300001][2];
     
    void dfs(int cur){
        bool flag = false;
        
        for(int i=0; i<v[cur].size(); i++){
            int next = v[cur][i];
            
            dfs(next);
            
            dp[cur][0+= min(dp[next][0], dp[next][1]);
            dp[cur][1+= min(dp[next][0], dp[next][1]);
            
            if(dp[next][0<= dp[next][1]) {
                flag = true;
            }
        }
        
        // 리프노드여도 리턴
        if(flag || v[cur].size()==0return;
        
        // dp[cur][1] 갱신시 팀원 모두가 dp[next][1]이 최소일 때
        long long mm = INF;
        
        for(int i=0; i<v[cur].size(); i++){
            int next = v[cur][i];
            mm = min(mm, dp[next][0- dp[next][1]);
        }
        
        dp[cur][1+= mm;
        
        return
    }
     
    int solution(vector<int> sales, vector<vector<int>> links) {
        int answer = 0;
        
        for(int i=0; i<sales.size(); i++){
            dp[i+1][0= sales[i];
        }
        
        
        for(int i=0; i<links.size(); i++){
            v[links[i][0]].push_back(links[i][1]);
        }
        
        dfs(1);
        
        answer = min(dp[1][0], dp[1][1]);
        
        return answer;
    }
    cs
     
Designed by Tistory.