Problem Solving/Programmers

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

limdef 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