LeetCode 1049. 最后一塊石頭的重量 II

題目描述

有一堆石頭,每塊石頭的重量都是正整數(shù)。

每一回合,從中選出任意兩塊石頭,然后將它們一起粉碎。假設(shè)石頭的重量分別為 x 和 y,且 x <= y。那么粉碎的可能結(jié)果如下:

如果 x == y,那么兩塊石頭都會被完全粉碎;
如果 x != y,那么重量為 x 的石頭將會完全粉碎,而重量為 y 的石頭新重量為 y-x。
最后,最多只會剩下一塊石頭。返回此石頭最小的可能重量。如果沒有石頭剩下,就返回 0。
示例:

輸入:[2,7,4,1,8,1]
輸出:1
解釋:
組合 2 和 4,得到 2,所以數(shù)組轉(zhuǎn)化為 [2,7,1,8,1],
組合 7 和 8,得到 1,所以數(shù)組轉(zhuǎn)化為 [2,1,1,1],
組合 2 和 1,得到 1,所以數(shù)組轉(zhuǎn)化為 [1,1,1],
組合 1 和 1,得到 0,所以數(shù)組轉(zhuǎn)化為 [1],這就是最優(yōu)值。

題目分析

  1. 由于抵消可放回,所以可以將題目轉(zhuǎn)換為分為兩堆石頭,這兩堆石頭重量差額最小。
  2. 所以轉(zhuǎn)化為經(jīng)典的01背包,背包的容量為sum/2所獲得的石頭的最大價(jià)值。

C++ 代碼

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int sum = 0;
        for(int i = 0; i < stones.size(); i++) {
            sum += stones[i];
        }
        int cap = sum/2;
        vector<int> dp(cap+5, 0);
        for(int i = 0; i < stones.size();i++) {
            for(int j = cap; j >= stones[i]; j--) {
                dp[j] = max(dp[j], dp[j-stones[i]] + stones[i]);
            }
        }
        
        return sum - 2*dp[cap];
    }
};
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容