1049 最後一塊石頭的重量 II

2022-10-01 17:57:10 字數 1984 閱讀 1928

有一堆石頭,用整數陣列stones表示。其中stones[i]表示第i塊石頭的重量。

每一回合,從中選出任意兩塊石頭,然後將它們一起粉碎。假設石頭的重量分別為xy,且x <= y。那麼粉碎的可能結果如下:

最後,最多隻會剩下一塊石頭。返回此石頭最小的可能重量。如果沒有石頭剩下,就返回0

示例 1:

輸入:stones = [2,7,4,1,8,1]

輸出:1

解釋:組合 2 和 4,得到 2,所以陣列轉化為 [2,7,1,8,1],

組合 7 和 8,得到 1,所以陣列轉化為 [2,1,1,1],

組合 2 和 1,得到 1,所以陣列轉化為 [1,1,1],

組合 1 和 1,得到 0,所以陣列轉化為 [1],這就是最優值。

示例 2:

輸入:stones = [31,26,33,21,40]

輸出:5

示例 3:

輸入:stones = [1,2]

輸出:1

最值問題一般都用動態規劃來解決。其實本題和416.分割等和子集

很相似,也是可以採用01揹包來解決。

根據題意,本題其實就是把一堆石頭分成兩堆,求兩堆石頭重量差最小值。要想讓兩堆石頭的差值盡可能小,則兩堆石頭的總重量應盡可能地接近於所有石頭的總重量/2

我們可以明確:物品就是石頭,物品的重量和價值就是每一塊石頭的重量,揹包的容量就是所有石頭的總重量/2

動態規劃五部曲:

確定dp陣列以及其下標的含義

dp[j]表示為容量為j的揹包最多可以背的石頭重量

確定遞推公式

根據01揹包基礎

中對遞推公式的推導可知,本題的遞推公式為dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])

dp陣列的初始化

dp[j] = 0

確定遍歷順序

只能先遍歷物品,再遍歷揹包。 注意這種方式揹包的遍歷順序是不一樣的,要從大往小遍歷。

舉例推導dp陣列

以 stones = [2,4,1,1] 為例

1049 最後一塊石頭的重量 II

1049.最後一塊石頭的重量 ii 有一堆石頭,每塊石頭的重量都是正整數。每一回合,從中選出任意兩塊石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x y。那麼粉碎的可能結果如下 如果 x y,那麼兩塊石頭都會被完全粉碎 如果 x y,那麼重量為 x 的石頭將會完全粉碎,而重量為 y...

最後一塊石頭重量

有一堆石頭,每塊石頭的重量都是正整數。每一回合,從中選出兩塊 最重的 石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x y。那麼粉碎的可能結果如下 如果 x y,那麼兩塊石頭都會被完全粉碎 如果 x y,那麼重量為 x 的石頭將會完全粉碎,而重量為 y 的石頭新重量為 y x。最後...

C語言重構 1049 最後一塊石頭的重量 II

所有題目源 git位址 題目有一堆石頭,每塊石頭的重量都是正整數。每一回合,從中選出任意兩塊石頭,然後將它們一起粉碎。假設石頭的重量分別為 x 和 y,且 x y。那麼粉碎的可能結果如下 如果 x y,那麼兩塊石頭都會被完全粉碎 如果 x y,那麼重量為 x 的石頭將會完全粉碎,而重量為 y 的石頭...