Leetcode Java Minimum Cost to Merge Stones
업데이트:
문제
코드
class Solution {
public int mergeStones(int[] stones, int k) {
int length = stones.length;
if ((length - 1) % (k - 1) > 0) {
return -1;
}
int[] sum = new int[length + 1];
for (int i = 0; i < length; i++) {
sum[i + 1] = sum[i] + stones[i];
}
int[][] dp = new int[length][length];
for (int end = k; end <= length; end++) {
for (int start = 0; start + end <= length; start++) {
int max = start + end - 1;
dp[start][max] = Integer.MAX_VALUE;
for (int mid = start; mid < max; mid += k - 1) {
dp[start][max] = Math.min(dp[start][max], dp[start][mid] + dp[mid + 1][max]);
}
if ((max - start) % (k - 1) == 0) {
dp[start][max] += sum[max + 1] - sum[start];
}
}
}
return dp[0][length - 1];
}
}
결과
설명
-
stones 내 연속된 k개의 값을 더해 최후의 하나의 값을 만들기 위한 각 부분 합을 더한 값이 최소가 되는 값을 구하는 문제이다.
-
length는 stones의 길이를 저장한 변수이다.
-
$\frac{length - 1}{k - 1}$의 결과가 정수로 떨어지지 않은 경우, k개씩 값을 더해서 최후의 하나의 값이 되지 않으므로 -1을 주어진 문제의 결과로 반환한다.
- 문제 풀이에 필요한 변수를 정의한다.
- sum은 각 위치 별 합계를 저장할 변수로, $length + 1$ 크기로 초기화하고 두 번째 위치부터 이전까지 값들의 합을 더해 넣어준다.
- dp는 부분 합을 더한 값이 최소가 되는 값을 찾기 위한 배열로, $length \times length$ 크기의 2차원 배열로 초기화한다.
- k부터 length 이하까지 end를 증가시키고, 0부터 $start + end$가 length 이하일 때 까지 start를 증가시키며 아래를 반복한다.
- max는 start번째 반복의 최대 위치인 $start + end - 1$을 넣어준다.
- dp[start][max]의 값에 정수의 최댓값을 넣어준다.
- start부터 max 미만까지 mid를 $k - 1$씩 증가시키며 아래를 수행한다.
- dp[start][max]의 값에 dp[start][max]의 값과 dp[start][mid]의 값에 dp[$mid + 1$][max]의 값을 더한 값 중 작은 값을 넣어준다.
- $\frac{max - start}{k - 1}$의 결과가 정수로 떨어지는 경우, dp[start][max]에 sum[max + 1]의 값에 sum[start]의 값을 뺀 start번째 값에서 max까지의 값의 합을 더해준다.
- 반복이 완료되면 문제의 조건에 대한 값이 최소가 되는 dp[0][$length - 1$]의 값을 주어진 문제의 결과로 반환한다.
소스
Sample Code는 여기에서 확인 가능합니다.
댓글남기기