目录
一、01背包
01背包不可重复,外层循环遍历nums,内参循环遍历targets,逆序:
如:将一堆石头分成2堆,求这2堆石头重量的最小差值。
class Solution:
def lastStoneWeightII(self, stones: list) -> int:
stoneSum = sum(stones)
target = stoneSum>>1 # 求不超过target的最大和
ls = [0 for i in range(target+1)]
for item in stones:
# print(target,item-1)
for j in range(target,item-1,-1):
# print('yes')
ls[j] = max(ls[j],ls[j-item]+item)
print(ls)
return stoneSum - 2*ls[target]
if __name__ == '__main__':
stones = [1,2,6]
s = Solution()
print(s.lastStoneWeightII(stones))
二、完全背包
完全背包可以重复,外层循环遍历nums,内层循环遍历targets,顺序
如:给一个正整数n,求由完全平方数(例如1,4,9,16,25等等)加起来构成它的最小个数
class Solution:
def sqrtFunc(self,n):
"""二分法求sqrt"""
if n == 1:
return 1
x = n/2
delta = 1e-10
left = 0
right = n
while abs(x*x-n) > delta:
if x*x > n:
right = x
x = (left+right)/2
else:
left = x
x = (left+right)/2
return int(x)+1
def numSqures(self,n:int)->int:
# 完全平方n需要的最小个数
# 完全背包问题
maxnum = self.sqrtFunc(n)
print(maxnum)
nums = [i for i in range(1,maxnum+1)]
# print(nums)
target = n
# 需要维护的数组
ls = [n for i in range(n+1)] # 初始化最大值
ls[0] = 0
for num in nums: # 外层循环nums
for j in range(num*num,target+1): # 内参循环target,正序
ls[j] = min(ls[j],ls[j-num*num]+1)
# print(ls[n])
return ls[n]
if __name__ == '__main__':
s = Solution()
print(s.numSqures(49))