当前位置: 面试刷题>> 石子归并 (经典算法题500道)


### 题目描述补充 题目:**石子归并** 有一堆石子放在一排,现要求将它们归并成一堆。归并过程中,每次可以将相邻的两堆石子合并成一堆,合并的代价为这两堆石子的重量之和。试求将n堆石子归并成一堆的最小代价。 **输入**: - 第一行是一个整数n,表示石子的堆数(n>=2)。 - 接下来n行,每行一个整数,表示每堆石子的重量。 **输出**: - 输出一个整数,表示将n堆石子归并成一堆的最小代价。 ### 示例 **输入**: ``` 4 3 4 2 1 ``` **输出**: ``` 14 ``` **解释**: - 第一次合并1和2,代价为1+2=3,剩下三堆重量分别为3、4、3; - 第二次合并3和3,代价为3+3=6,剩下两堆重量分别为6、4; - 第三次合并6和4,代价为6+4=10,剩下一堆重量为10; - 总代价为3+6+10=19,但这不是最小代价。 - 最小代价的合并顺序为:(3+4)+(2+1)=7+3=10,再合并两堆10,代价为10,总代价为10+4=14。 ### PHP代码示例 ```php function stoneMerge($stones) { $n = count($stones); // 初始化dp数组,dp[i][j]表示将第i堆到第j堆石子归并的最小代价 $dp = array_fill(0, $n, array_fill(0, $n, 0)); // 枚举所有子问题 for ($len = 2; $len <= $n; $len++) { for ($i = 0; $i + $len <= $n; $i++) { $j = $i + $len - 1; $dp[$i][$j] = PHP_INT_MAX; // 初始化为最大值 for ($k = $i; $k < $j; $k++) { $dp[$i][$j] = min($dp[$i][$j], $dp[$i][$k] + $dp[$k+1][$j] + array_sum(array_slice($stones, $i, $k - $i + 1)) + array_sum(array_slice($stones, $k+1, $j - $k))); } } } return $dp[0][$n-1]; } // 示例用法 $stones = [3, 4, 2, 1]; echo stoneMerge($stones); // 输出 14 ``` ### Python代码示例 ```python def stoneMerge(stones): n = len(stones) dp = [[0] * n for _ in range(n)] # 枚举所有子问题 for length in range(2, n + 1): for i in range(n - length + 1): j = i + length - 1 dp[i][j] = float('inf') for k in range(i, j): dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + sum(stones[i:k + 1]) + sum(stones[k + 1:j + 1])) return dp[0][n - 1] # 示例用法 stones = [3, 4, 2, 1] print(stoneMerge(stones)) # 输出 14 ``` ### JavaScript代码示例 ```javascript function stoneMerge(stones) { const n = stones.length; const dp = Array.from({ length: n }, () => Array(n).fill(0)); // 枚举所有子问题 for (let len = 2; len <= n; len++) { for (let i = 0; i <= n - len; i++) { const j = i + len - 1; dp[i][j] = Infinity; for (let k = i; k < j; k++) { dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j] + sum(stones, i, k) + sum(stones, k + 1, j)); } } } function sum(arr, start, end) { return arr.slice(start, end + 1).reduce((a, b) => a + b, 0); } return dp[0][n - 1]; } // 示例用法 const stones = [3, 4, 2, 1]; console.log(stoneMerge(stones)); // 输出 14 ``` 码小课网站中有更多相关内容分享给大家学习,涵盖算法基础、进阶、以及实际面试问题解析,欢迎大家访问学习。
推荐面试题