题目链接:1049. 最后一块石头的重量 II - 力扣(LeetCode)
思路:要想两堆石头最终想减最小,其实就是要将两堆石头尽可能分得近,即最理想情况target = sum(stones) // 2; 每个石头只能用一次,而且要想尽可能大地将石头放入,所以可以考虑用01背包。
class Solution(object):
def lastStoneWeightII(self, stones):
"""
:type stones: List[int]
:rtype: int
"""
target = sum(stones) // 2
dp = [0] * (target + 1)
for i in range(len(stones)):
for j in range(target, stones[i] - 1, -1):
dp[j] = max(dp[j], dp[j-stones[i]] + stones[i])
for i in range(len(dp)-1, -1, -1):
if dp[i] == i:
part_1 = dp[i]
part_2 = sum(stones) - dp[i]
return abs(part_1 - part_2)
class Solution(object):
def findTargetSumWays(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
# leftSum - rightSum = target
# leftSum + rightSum = sum
# rightSum = sum - leftSum
# leftSum - sum + leftSum = target
# leftSum = (sum + target) // 2
# 所以找leftSum 即可
temp = sum(nums) + target
if temp % 2 != 0:
return 0
if abs(target) > sum(nums):
return 0
n = temp // 2
dp = [0] * (n + 1)
dp[0] = 1 # 背包容量为0不放的情况是1
for i in range(len(nums)):
for j in range(n, nums[i] - 1, -1):
dp[j] += dp[j - nums[i]] #当前容量减去要放的容量的个数 + 当前的次数
return dp[n]
class Solution(object):
def findMaxForm(self, strs, m, n):
"""
:type strs: List[str]
:type m: int
:type n: int
:rtype: int
"""
dp = [[0] * (n + 1) for _ in range(m + 1)]
for s in strs: #遍历物品
zeroNum = s.count('0')
oneNum = len(s) - zeroNum
for i in range(m, zeroNum - 1, -1):
for j in range(n, oneNum -1, -1):
dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1) #要么dp[i-当前字符串用掉的0][j-当前字符串用掉的1]
return dp[m][n] #装m个0 和n个1的最大子集长度是多少