一、限定重量,求最大价值
class Solution:
"""
目标函数:价值最大
限制条件:背包重量
"""
def bigValue(self)->(int,list):
fruit = {'李子':[4,4500],'苹果':[5,5700],'橘子':[2,2250],'草莓':[1,1100],'甜瓜':[6,6700]}
capacity = 8 # 背包限制条件
values = list(fruit.values())
keys = list(fruit.keys())
f = [] # 选中的水果
maxval = 0 # 最大价值
cnt = -1 # 是第几轮发现的最大值
for i in range(len(values)):
sumVal = 0
size = 0
f1 = []
index = i # key的值
flag = False # 在本轮有没有更新最大值
for item in values[i:]:
sumVal +=item[1]
size +=item[0]
f1.append(keys[index])
if size > capacity:
sumVal -=item[1]
size -=item[0]
f1.pop()
index +=1
continue
if sumVal > maxval:
maxval = sumVal
flag = True
index +=1
if flag:
cnt+=1
f.append(f1)
print(f)
return maxval,f[cnt]
if __name__ == '__main__':
s = Solution()
re1,re2 = s.bigValue()
print('最大价值:',re1)
print('最大价值的组合:',re2)
输出:
[['李子', '橘子', '草莓']]
[['李子', '橘子', '草莓'], ['苹果', '橘子', '草莓']]
[['李子', '橘子', '草莓'], ['苹果', '橘子', '草莓'], ['橘子', '草莓']]
[['李子', '橘子', '草莓'], ['苹果', '橘子', '草莓'], ['橘子', '草莓'], ['草莓', '甜瓜']]
[['李子', '橘子', '草莓'], ['苹果', '橘子', '草莓'], ['橘子', '草莓'], ['草莓', '甜瓜'], ['甜瓜']]
最大价值: 9050
最大价值的组合: ['苹果', '橘子', '草莓']
二、转成01背包问题
2.1 题目描述:
给定一个只包含正整数的非空数组,是否可以将这个数组分割成2个子集, 使2个子集的元素和相等
# 可以转成01背包问题
# 目标函数:和为总和的一半
# 约束条件:小于数组长度
class Solution:
def canPartition(self,nums)->bool:
s = sum(nums)
if s % 2 != 0:
return False
sumT = 0
for i in range(len(nums)):
for item in nums[i:]:
sumT +=item
if sumT > s/2: # 中间发现大于一半的和,跳过这个数
sumT -=item
continue
if sumT == s/2:
return True
return False
if __name__ == '__main__':
s = Solution()
print(s.canPartition([1,5,11,5]))
输出:
True