Minimum Cost to Merge Stones
Link
Description
There are n
piles of stones
arranged in a row. The i
-th pile has stones[i]
stones.
A move consists of merging exactly k
consecutive piles into one pile, and the cost of this move is equal to the total number of stones in these k
piles.
Return the minimum cost to merge all piles of stones into one pile. If it is impossible, return -1
.
Example 1:
- Input:
stones = [3,2,4,1], k = 2
- Output:
20
- Explanation:
| We start with [3, 2, 4, 1].
We merge [3, 2] for a cost of 5, and we are left with [5, 4, 1].
We merge [4, 1] for a cost of 5, and we are left with [5, 5].
We merge [5, 5] for a cost of 10, and we are left with [10].
The total cost was 20, and this is the minimum possible.
|
Example 2:
- Input:
stones = [3,2,4,1], k = 3
- Output:
-1
- Explanation:
After any merge operation, there are 2 piles left, and we can't merge anymore. So the task is impossible.
Example 3:
- Input:
stones = [3,5,1,2,6], k = 3
- Output:
25
- Explanation:
| We start with [3, 5, 1, 2, 6].
We merge [5, 1, 2] for a cost of 8, and we are left with [3, 8, 6].
We merge [3, 8, 6] for a cost of 17, and we are left with [17].
The total cost was 25, and this is the minimum possible.
|
Constraints:
n == stones.length
1 <= n <= 30
1 <= stones[i] <= 100
2 <= k <= 30
Solution
| class Solution {
public:
int mergeStones(vector<int>& stones, int k) {
int n = stones.size();
if ((n - 1) % (k - 1)) return -1;
int s[n + 1];
s[0] = 0;
for (int i = 0; i < n; i++) s[i + 1] = s[i] + stones[i];
int f[n][n];
for (int i = n - 1; i >= 0; i--) {
f[i][i] = 0;
for (int j = i + 1; j < n; j++) {
f[i][j] = INT_MAX;
for (int m = i; m < j; m += k - 1) {
f[i][j] = min(f[i][j], f[i][m] + f[m + 1][j]);
}
if ((j - i) % (k - 1) == 0)
f[i][j] += s[j + 1] - s[i];
}
}
return f[0][n - 1];
}
};
|