Skip to content

Commit 03baeb8

Browse files
committed
nsun9505 solved 매출하락최소화
1 parent 4d1fe61 commit 03baeb8

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# [2021 KAKAO BLIND RECURUITMENT] 매출 하락 최소화 - JAVA
2+
3+
## 분류
4+
> DP
5+
>
6+
> 트리 DP
7+
8+
## 코드
9+
```java
10+
import java.util.ArrayList;
11+
12+
public class Solution {
13+
static ArrayList<Element>[] graph;
14+
static boolean[] isVisited;
15+
static int[][] dp;
16+
static int N;
17+
public int solution(int[] sales, int[][] links) {
18+
int answer = 0;
19+
N = sales.length;
20+
graph = new ArrayList[N+1];
21+
dp = new int[N+1][2];
22+
isVisited = new boolean[N+1];
23+
Element[] arr = new Element[N+1];
24+
for(int i=1; i<=N; i++) {
25+
graph[i] = new ArrayList<>();
26+
dp[i][1] = sales[i-1];
27+
arr[i] = new Element(i, sales[i-1]);
28+
}
29+
30+
for(int i=0; i<links.length; i++)
31+
graph[links[i][0]].add(arr[links[i][1]]);
32+
33+
DFS(1);
34+
35+
answer = Math.min(dp[1][0], dp[1][1]);
36+
37+
return answer;
38+
}
39+
40+
public static void DFS(int cur){
41+
isVisited[cur] = true;
42+
43+
if(graph[cur].size() == 0)
44+
return;
45+
46+
int sum = 0;
47+
int cnt = 0;
48+
for(Element next : graph[cur]){
49+
if(isVisited[next.vertex])
50+
continue;
51+
52+
DFS(next.vertex);
53+
if(dp[next.vertex][0] > dp[next.vertex][1]){
54+
sum += dp[next.vertex][1];
55+
cnt++;
56+
} else {
57+
sum += dp[next.vertex][0];
58+
}
59+
}
60+
61+
dp[cur][1] += sum;
62+
if(cnt > 0)
63+
dp[cur][0] = sum;
64+
else {
65+
int min = Integer.MAX_VALUE;
66+
for (Element next : graph[cur])
67+
min = Math.min(min, dp[next.vertex][1] - dp[next.vertex][0]);
68+
dp[cur][0] = sum + min;
69+
}
70+
}
71+
72+
public static void main(String[] args) {
73+
Solution s = new Solution();
74+
System.out.println(s.solution( new int[]{5, 6, 5, 3, 4}, new int[][]{{2, 3}, {1, 4}, {2, 5}, {1, 2}}));
75+
}
76+
77+
static class Element{
78+
int vertex;
79+
int val;
80+
81+
public Element(int vertex, int val) {
82+
this.vertex = vertex;
83+
this.val = val;
84+
}
85+
}
86+
}
87+
```
88+
89+
## 문제 풀이
90+
와우 어려워유 테이블 정의까지는 했는데 식을 도출하지 못해서 카카오 해설을 봤습니다.
91+
92+
값을 구하기 위해서 DFS로 내려오면서 마지막에 1번 노드에서 계산을 마치면 됩니다.
93+
94+
테이블 정의는 다음과 같습니다.
95+
- dp[i][0] : i번째 노드가 루트인 서브트리에서, i번 노드가 워크숍에 불참석
96+
- dp[i][1] : i번째 노드가 루트인 서브트리에서, i번 노드가 워크숍에 참석
97+
98+
dp[i][1]은 i번째 노드가 워크숍에 참석한다는 의미이므로
99+
- i의 자식들은 워크숍에 참석을 하든 말든,
100+
- 즉, 자식들에게 또 다른 자식이 있든 말든, i는 워크숍에 참석하므로 자식 노드가 또 다른 자식 노드를 갖지 않는다면 0이 주어질 것이고 해당 자식 노드가 또 다른 자식 노드를 갖는다면 해당 팀에서 최솟값이 dp[k][0] 또는 dp[k][1]에 세팅될 것입니다.
101+
- 그러므로 각각의 자식 노드의 워크숍 참석 또는 불참석에 대한 최솟값을 모두 더한 값과 i번째가 워크숍에 참석하는 비용인 sales[i](=dp[i][1])을 더해서 dp[i][1]에 저장하면 됩니다.
102+
103+
i번째 노드의 모든 자식 노드에 대해서 합을 구합니다.
104+
- sum += Math.min(dp[k][0], dp[k][1])
105+
- k는 자식 노드를 의미합니다.
106+
107+
dp[i][0]은 i번째가 속하는 팀(i를 루트로 하는 서브트리)에서 i가 참석하지 않는 경우입니다.
108+
- i번째 자식들 중에서 최소가 되는 값을 dp[i][0]에 세팅해야 합니다.
109+
- 그래서 sum 값을 구할 때 dp[k][0] > dp[k][1]을 만족하는 k가 한 개라도 있다면 dp[i][0]에는 sum 값을 넣어줍니다.
110+
- 즉, i의 자식 노드들 중에서 자식을 가지는 노드들이 존재한다는 의미이고, k번째 노드는 i번째가 속한 팀에서 워크숍에 참석한다는 의미입니다.
111+
- 그러므로 dp[i][0]의 값은 sum이 됩니다.
112+
- 또는, dp[k][0] > dp[k][1]을 만족하는 k가 하나도 없는 경우는 i의 자식 노드들 중에서 워크숍에 참석하는 도느가 없다는 의미입니다.
113+
- 그래서 하나의 노드를 골라서 팀에서 하나라도 참여하도록 해야 합니다.
114+
- 참석 시킬 노드를 찾기 위해서 매출 손해가 가장 적게 발생하는 k를 찾기 위해 minGap = dp[k][1] - dp[k][0]이 최소인 k를 참석시키도록 합니다.
115+
- dp[i][0]에는 sum + minGap 값을 넣어주면 됩니다.
116+
117+
DFS로 탐색을 하기 때문에 답으로는 dp[1][0]과 dp[1][1] 중에서 작은 값을 출력하면 됩니다.
118+
119+
## 후기
120+
트리 DP 참 어렵습니다..
121+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import java.util.ArrayList;
2+
3+
public class Solution {
4+
static ArrayList<Element>[] graph;
5+
static boolean[] isVisited;
6+
static int[][] dp;
7+
static int N;
8+
public int solution(int[] sales, int[][] links) {
9+
int answer = 0;
10+
N = sales.length;
11+
graph = new ArrayList[N+1];
12+
dp = new int[N+1][2];
13+
isVisited = new boolean[N+1];
14+
Element[] arr = new Element[N+1];
15+
for(int i=1; i<=N; i++) {
16+
graph[i] = new ArrayList<>();
17+
dp[i][1] = sales[i-1];
18+
arr[i] = new Element(i, sales[i-1]);
19+
}
20+
21+
for(int i=0; i<links.length; i++)
22+
graph[links[i][0]].add(arr[links[i][1]]);
23+
24+
DFS(1);
25+
26+
answer = Math.min(dp[1][0], dp[1][1]);
27+
28+
return answer;
29+
}
30+
31+
public static void DFS(int cur){
32+
isVisited[cur] = true;
33+
34+
if(graph[cur].size() == 0)
35+
return;
36+
37+
int sum = 0;
38+
int cnt = 0;
39+
for(Element next : graph[cur]){
40+
if(isVisited[next.vertex])
41+
continue;
42+
43+
DFS(next.vertex);
44+
if(dp[next.vertex][0] > dp[next.vertex][1]){
45+
sum += dp[next.vertex][1];
46+
cnt++;
47+
} else {
48+
sum += dp[next.vertex][0];
49+
}
50+
}
51+
52+
dp[cur][1] += sum;
53+
if(cnt > 0)
54+
dp[cur][0] = sum;
55+
else {
56+
int min = Integer.MAX_VALUE;
57+
for (Element next : graph[cur])
58+
min = Math.min(min, dp[next.vertex][1] - dp[next.vertex][0]);
59+
dp[cur][0] = sum + min;
60+
}
61+
}
62+
63+
public static void main(String[] args) {
64+
Solution s = new Solution();
65+
System.out.println(s.solution( new int[]{5, 6, 5, 3, 4}, new int[][]{{2, 3}, {1, 4}, {2, 5}, {1, 2}}));
66+
}
67+
68+
static class Element{
69+
int vertex;
70+
int val;
71+
72+
public Element(int vertex, int val) {
73+
this.vertex = vertex;
74+
this.val = val;
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)