알고리즘/백준
1932번 - 정수 삼각형
fleur75
2023. 7. 18. 21:35
1️⃣ DP
✏️ 풀이 과정
정수 삼각형의 모양을 보고 어떤 식으로 저장해야 할 지 난감하다고 느끼기 쉽지만 다이나믹 프로그래밍을 이용하기로 마음먹으면 의외로 인덱스 0부터 순서대로 집어넣고 간단하게 해결할 수 있습니다.
기본 아이디어는 배열을 하나 만들고 삼각형의 꼭대기를 0번째 단계, 마지막 줄을 n-1번째 단계라 할 때 배열에 해당 단계의 해당 인덱스의 입력을 선택했을 때의 최댓값이 얼마인지를 계속 업데이트해주는 것입니다.
왼쪽 끝은 항상 이전 결과의 왼쪽 끝에서만 선택할 수 있고 오른쪽 끝 역시 이전 결과의 오른쪽끝에서만 선택할 수 있습니다. 그 이외의 경우에는 인덱스-1과 인덱스 위치의 결과 중 큰 것을 선택해 현재 입력에 더하면 됩니다.
업데이트를 마쳤다면 주어진 n 크기의 배열이 완성되었을텐데 배열에서 가장 큰 수를 찾아 출력하면 풀이가 종료됩니다.
⏱ 시간 복잡도
이중 루프가 있기 때문에 시간 복잡도는 O(n^2)이 됩니다. j가 i번만 반복되기 때문에 더 낫지 않을까 생각이 들 수 있지만 실제로 횟수를 세보면 1+2+...+n = n(n+1)/2 등차수열의 합과 같기 때문에 O(n^2)이 됩니다. n이 500까지 가능하기 때문에대략 계산량 250000으로 시간 내에 해결할 수 있음을 예측할 수 있습니다.
💻 코드
Java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main{
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int n = Integer.parseInt(br.readLine());
int[] input = new int[n];
int[] res = new int[n];
int[] tmp;
for(int i=1;i<=n;i++) {
st = new StringTokenizer(br.readLine());
tmp = Arrays.copyOf(res, res.length);
for(int j=0;j<i;j++) {
input[j] = Integer.parseInt(st.nextToken());
if(j == 0) {
res[j] = tmp[j] + input[j];
} else if(j == i-1) {
res[j] = tmp[j-1] + input[j];
} else {
res[j] = Math.max(tmp[j-1], tmp[j]) + input[j];
}
}
}
int max = Integer.MIN_VALUE;
for(int i=0;i<n;i++) {
if(res[i] > max) {
max = res[i];
}
}
System.out.println(max);
br.close();
}
}