力扣 5063 最后一块石头的重量 & II
思路:每次循环,sort将这堆石头从大到小排序,拿出最重的两块石头粉碎,若粉碎后的值不为0,则存入stones中,再做sort从大到小排序,直到stones的size<2为止。
class Solution { public: int lastStoneWeight(vector<int>& stones) { int s = 0; sort(stones.begin(), stones.end(), greater<int>()); while(stones.size()>=2){ s = stones[0] - stones[1]; stones.erase(stones.begin(), stones.begin()+2); if(s != 0){ stones.push_back(s); sort(stones.begin(), stones.end(), greater<int>()); } } return stones.empty()? 0 : stones[0]; } };
思路:相当于把这堆石头分为两堆,让其中一堆的值尽可能的接近于输入总和的一半。
动态规划:维护一个dp[i][j] :行表示索引为i时对应的这块石头,最大的重量为j时,得到的当前堆的重量。
class Solution { public: int lastStoneWeightII(vector<int>& stones) { int size = stones.size(); if(size==0) return 0; else if(size==1) return size; int sum = 0; for(int i=0; i<size; i++) sum += stones[i]; int dp[size+1][sum/2 +1] = {}; for(int i=1; i<size+1; i++){ for(int j = 1; j< sum/2 + 1 ; j++){ if(stones[i-1] <= j) dp[i][j] = max(dp[i-1][j], dp[i-1][j-stones[i-1]] + stones[i-1]); else dp[i][j] = dp[i-1][j]; } } return (sum - 2*dp[size][sum/2]); } };