最後一塊石頭的重量||
阿新 • • 發佈:2021-08-09
題目連結:https://leetcode-cn.com/problems/last-stone-weight-ii
題目描述:
有一堆石頭,用整數陣列stones 表示。其中stones[i] 表示第 i 塊石頭的重量。
每一回合,從中選出任意兩塊石頭,然後將它們一起粉碎。假設石頭的重量分別為x 和y,且x <= y。那麼粉碎的可能結果如下:
如果x == y,那麼兩塊石頭都會被完全粉碎;
如果x != y,那麼重量為x的石頭將會完全粉碎,而重量為y的石頭新重量為y-x。
最後,最多隻會剩下一塊 石頭。返回此石頭 最小的可能重量 。如果沒有石頭剩下,就返回 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
提示:
1 <= stones.length <= 30
1 <= stones[i] <= 100
題解:
本題是儘量讓石頭分成重量相同的兩堆,相撞之後剩下的石頭最小,這樣就化解成01揹包問題了。
class Solution { public: int lastStoneWeightII(vector<int>& stones) { int sum = 0; for(int &item : stones) { sum += item; } int target = sum / 2; vector<int> dp(1501, 0); //dp[j]:容量為j時,揹包所裝的石頭總和為dp[j] for(int i = 0; i < stones.size(); i++) { for(int j = target; j>= stones[i]; j--) { dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]); } } return (sum - dp[target]) - dp[target]; } };