You are given an array of integers stones
where stones[i]
is the weight of the ith
stone.
We are playing a game with the stones. On each turn, we choose any two stones and smash them together. Suppose the stones have weights x
and y
with x <= y
. The result of this smash is:
- If
x == y
, both stones are destroyed, and - If
x != y
, the stone of weightx
is destroyed, and the stone of weighty
has new weighty - x
.
At the end of the game, there is at most one stone left.
Return the smallest possible weight of the left stone. If there are no stones left, return 0
.
转化为0-1背包问题,相当于分成两个数组,各自的和最接近。
背包容量sum//2,能获得的最大价值。
最终两个背包的差值为2*(sum_stones//2 - dp[target])
class Solution:
def lastStoneWeightII(self, stones: List[int]) -> int:
W = 1500
size = len(stones)
dp = [0 for _ in range(W + 1)]
target = sum(stones) // 2
for i in range(1, size + 1):
for w in range(target, stones[i - 1] - 1, -1):
dp[w] = max(dp[w], dp[w - stones[i - 1]] + stones[i - 1])
return sum(stones) - dp[target] * 2