1000:合并石头的最低成本

This commit is contained in:
轩辕龙儿 2023-04-04 21:34:59 +08:00
parent 1c8185c292
commit 8f93e04dbe
2 changed files with 145 additions and 0 deletions

View File

@ -0,0 +1,96 @@
//// N 堆石头排成一排 i 堆中有 stones[i] 块石头
//
// 每次移动move需要将连续的 K 堆石头合并为一堆而这个移动的成本为这 K 堆石头的总数
//
// 找出把所有石头合并成一堆的最低成本如果不可能返回 -1
//
//
//
// 示例 1
//
// 输入stones = [3,2,4,1], K = 2
//输出20
//解释
// [3, 2, 4, 1] 开始
//合并 [3, 2]成本为 5剩下 [5, 4, 1]
//合并 [4, 1]成本为 5剩下 [5, 5]
//合并 [5, 5]成本为 10剩下 [10]
//总成本 20这是可能的最小值
//
//
// 示例 2
//
// 输入stones = [3,2,4,1], K = 3
//输出-1
//解释任何合并操作后都会剩下 2 我们无法再进行合并所以这项任务是不可能完成的.
//
//
// 示例 3
//
// 输入stones = [3,5,1,2,6], K = 3
//输出25
//解释
// [3, 5, 1, 2, 6] 开始
//合并 [5, 1, 2]成本为 8剩下 [3, 8, 6]
//合并 [3, 8, 6]成本为 17剩下 [17]
//总成本 25这是可能的最小值
//
//
//
//
// 提示
//
//
// 1 <= stones.length <= 30
// 2 <= K <= 30
// 1 <= stones[i] <= 100
//
//
// Related Topics 数组 动态规划 👍 313 👎 0
package leetcode.editor.cn;
import java.util.Arrays;
// 1000:合并石头的最低成本
public class MinimumCostToMergeStones {
public static void main(String[] args) {
Solution solution = new MinimumCostToMergeStones().new Solution();
}
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {
public int mergeStones(int[] stones, int k) {
int size = stones.length;
if ((size - 1) % (k - 1) != 0) {
return -1;
}
int[][] dp = new int[size][size];
for (int i = 0; i < size; i++) {
Arrays.fill(dp[i], Integer.MAX_VALUE);
}
int[] sum = new int[size];
dp[0][0] = 0;
sum[0] = stones[0];
for (int i = 1; i < size; i++) {
dp[i][i] = 0;
sum[i] = sum[i - 1] + stones[i];
}
for (int len = 2; len <= size; len++) {
for (int start = 0; start < size && start + len - 1 < size; start++) {
int end = start + len - 1;
for (int p = start; p < end; p += k - 1) {
dp[start][end] = Math.min(dp[start][end], dp[start][p] + dp[p + 1][end]);
}
if ((end - start) % (k - 1) == 0) {
dp[start][end] += sum[end] - (start == 0 ? 0 : sum[start - 1]);
}
}
}
return dp[0][size - 1];
}
}
//leetcode submit region end(Prohibit modification and deletion)
}

View File

@ -0,0 +1,49 @@
<p><code>N</code> 堆石头排成一排,第 <code>i</code> 堆中有&nbsp;<code>stones[i]</code>&nbsp;块石头。</p>
<p>每次<em>移动move</em>需要将<strong>连续的</strong>&nbsp;<code>K</code>&nbsp;堆石头合并为一堆,而这个移动的成本为这&nbsp;<code>K</code>&nbsp;堆石头的总数。</p>
<p>找出把所有石头合并成一堆的最低成本。如果不可能,返回 <code>-1</code></p>
<p>&nbsp;</p>
<p><strong>示例 1</strong></p>
<pre><strong>输入:</strong>stones = [3,2,4,1], K = 2
<strong>输出:</strong>20
<strong>解释:</strong>
从 [3, 2, 4, 1] 开始。
合并 [3, 2],成本为 5剩下 [5, 4, 1]。
合并 [4, 1],成本为 5剩下 [5, 5]。
合并 [5, 5],成本为 10剩下 [10]。
总成本 20这是可能的最小值。
</pre>
<p><strong>示例 2</strong></p>
<pre><strong>输入:</strong>stones = [3,2,4,1], K = 3
<strong>输出:</strong>-1
<strong>解释:</strong>任何合并操作后,都会剩下 2 堆,我们无法再进行合并。所以这项任务是不可能完成的。.
</pre>
<p><strong>示例 3</strong></p>
<pre><strong>输入:</strong>stones = [3,5,1,2,6], K = 3
<strong>输出:</strong>25
<strong>解释:</strong>
从 [3, 5, 1, 2, 6] 开始。
合并 [5, 1, 2],成本为 8剩下 [3, 8, 6]。
合并 [3, 8, 6],成本为 17剩下 [17]。
总成本 25这是可能的最小值。
</pre>
<p>&nbsp;</p>
<p><strong>提示:</strong></p>
<ul>
<li><code>1 &lt;= stones.length &lt;= 30</code></li>
<li><code>2 &lt;= K &lt;= 30</code></li>
<li><code>1 &lt;= stones[i] &lt;= 100</code></li>
</ul>
<div><div>Related Topics</div><div><li>数组</li><li>动态规划</li></div></div><br><div><li>👍 313</li><li>👎 0</li></div>