01背包问题

一、限定重量,求最大价值

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

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值