문제링크 : https://www.acmicpc.net/problem/status/1516
1516번 맞힌 사람 - 1 페이지
모든 언어C++JavaPythonCC++17Java 8Python 3C11PyPy3C99C++98C++11C++14Java 8 (OpenJDK)Java 11C++20Python 2PyPy2RubyKotlin (JVM)Kotlin (Native)CythonSwiftTextC#node.jsGoGo (gccgo)Java 15DD (LDC)F# (Mono)PHPRust 2015Rust 2018PascalScalaLuaPerlRakuRuby 1.8R
www.acmicpc.net
접근 과정 :
- 어떤 건물을 짓기 전에, 지어야 하는 건물이 있다면 그 건물들을 모두 먼저 지어야 한다.
- 건물을 지을 수 있는 상황이라면, 여러 건물을 동시에 지을 수 있다.
- 즉, A건물을 짓기 위해서는 A건물을 짓는 시간 + (먼저 지어야하는 건물들의 최대시간) 이다.
- 각 건물의 시간을 저장하고, 먼저 지어야 하는 건물들을 저장한다.
- 해당 건물보다 먼저 지어햐 하는 건물들을 순회하면서 먼저 필요한 최대 시간을 구한다.
- 해당 건물을 짓는 시간에 먼저 필요한 최대 시간을 더해서 리턴한다.
- 계산된 건물의 시간은 DP배열에 저장하여, 재계산하지 않도록 한다.
** 먼저 지어야 하는 건물리스트를 저장하는 방법
1) Build클래스를 생성하여 노드처럼 엮어서 건물들의 관계를 저장하고 접근한다.
2) List<List>에 각 건물의 먼저 지어야 하는 건물 리스트를 저장한다.
소스 코드 및 결과 :
package BOJ;
/**
* 게임 개발
Build클래스와 Build[] BuildSequence를 통해 건물들간의 관계를 엮는다.
그리고 이를 통해 먼저 지어야하는 건물에 접근한다.
*/
import java.io.*;
import java.util.*;
public class BOJ1516 {
public static void main(String[] args) throws NumberFormatException, IOException {
new BOJ1516().solution();
}
void solution() throws NumberFormatException, IOException {
init();
StringBuilder answer = new StringBuilder();
for (int i = 1; i <= N; i++) {
answer.append(getNeedTime(i)).append("\n");
}
System.out.println(answer.toString().trim());
}
int N;
int[] time;
Build[] buildSequence;
int[] dp;
private class Build {
int num;
Build previous;
Build(int num, Build previous) {
this.num = num;
this.previous = previous;
}
}
void addSequence(int num, int previousNum) {
if (buildSequence[num] == null) {
buildSequence[num] = new Build(previousNum, null);
} else {
buildSequence[num] = new Build(previousNum, buildSequence[num]);
}
}
void init() throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
time = new int[N + 1];
buildSequence = new Build[N + 1];
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
time[i] = Integer.parseInt(st.nextToken());
while (true) {
int x = Integer.parseInt(st.nextToken());
if (x == -1) {
break;
}
addSequence(i, x);
}
}
dp = new int[N + 1];
}
int getNeedTime(int num) {
if (dp[num] != 0) {
return dp[num];
}
dp[num] = time[num];
int need = 0;
for (Build previous = buildSequence[num]; previous != null; previous = previous.previous) {
need = Math.max(need, getNeedTime(previous.num));
}
return dp[num]+=need;
}
}
package BOJ;
/**
*
* 게임 개발
List<List>를 통해 각 건물들의 먼저 지어햐 하는 건물리스트를 저장한다.
*
*/
import java.io.*;
import java.util.*;
public class BOJ1516_copy {
public static void main(String[] args) throws NumberFormatException, IOException {
new BOJ1516_copy().solution();
}
void solution() throws NumberFormatException, IOException {
init();
StringBuilder answer = new StringBuilder();
for (int i = 1; i <= N; i++) {
answer.append(getNeedTime(i)).append("\n");
}
System.out.println(answer.toString().trim());
}
int N;
int[] time;
List<List<Integer>> previous;
int[] dp;
void init() throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
N = Integer.parseInt(br.readLine());
time = new int[N + 1];
previous = new ArrayList<>();
previous.add(new ArrayList<>());
for (int i = 1; i <= N; i++) {
st = new StringTokenizer(br.readLine());
time[i] = Integer.parseInt(st.nextToken());
previous.add(new ArrayList<>());
while (true) {
int x = Integer.parseInt(st.nextToken());
if (x == -1) {
break;
}
previous.get(i).add(x);
}
}
dp = new int[N + 1];
}
int getNeedTime(int num) {
if (dp[num] != 0) {
return dp[num];
}
dp[num] = time[num];
int need = 0;
for (int p : previous.get(num)) {
need = Math.max(need, getNeedTime(p));
}
return dp[num] += need;
}
}
P.S
전반적인 방법의 차이는 없지만, 건물들의 관계 저장 방식에서 시간차이가 발생한다.
추가로 List<List> 대신 Map<Int, Set>구조를 쓰면 약간 더 많은 시간이 소모된다.
접근 방식에서 차이가 효율성 차이가 나는 것 같다.
'Algorithm' 카테고리의 다른 글
[백준 Gold 4] 4485 녹색 옷 입은 애가 젤다지? - Java (0) | 2022.01.26 |
---|---|
[백준 Silver 3] 1748 수 이어 쓰기 1 - Java (0) | 2022.01.16 |
[백준 Silver 2] 10451 순열 사이클 - Java (0) | 2022.01.14 |
[백준 Silver 4] 11656 접미사 배열 - Java (0) | 2022.01.13 |
[백준 Gold 2] 1766 문제집 - Java (0) | 2022.01.13 |