Day 46 代码随想录 单词拆分 多重背包

文章介绍了如何使用动态规划解决139.单词拆分问题,通过遍历单词字典并维护一个状态数组来判断给定字符串是否能由字典中的单词组成。接着,文章展示了两种方法解决多重背包问题,一种是将物品数量转换为0-1背包形式,另一种是在0-1背包的基础上增加遍历物品的数量。
摘要由CSDN通过智能技术生成


139. 单词拆分

   题目链接:139. 单词拆分
在这里插入图片描述

 
  这里强调顺序所以就先遍历背包再遍历物品
把第一次出现的单词标记为true,如果出现了后续的单词就可以标记true。

 
在这里插入图片描述

class Solution(object):
    def wordBreak(self, s, wordDict):
        """
        :type s: str
        :type wordDict: List[str]
        :rtype: bool
        """
        dp = [False]*(len(s) + 1)
        dp[0] = True
        # 遍历背包
        for j in range(1, len(s) + 1):
            # 遍历单词
            for word in wordDict:
                if j >= len(word):
                    if dp[j-len(word)]==True and word == s[j - len(word):j]:
                        dp[j]=True
                    else:
                        dp[j]=dp[j]
        return dp[-1]

 
在这里插入图片描述

多重背包问题

   题目链接:多重背包问题
在这里插入图片描述
在这里插入图片描述

 
  需要将多重背包变成0-1背包,具体代码如下:

def test_multi_pack1():
    '''版本一:改变物品数量为01背包格式'''
    weight = [1, 3, 4]
    value = [15, 20, 30]
    nums = [2, 3, 2]
    bag_weight = 10
    for i in range(len(nums)):
        # 将物品展开数量为1
        while nums[i] > 1:
            weight.append(weight[i])
            value.append(value[i])
            nums[i] -= 1
    
    dp = [0]*(bag_weight + 1)
    # 遍历物品
    for i in range(len(weight)):
        # 遍历背包
        for j in range(bag_weight, weight[i] - 1, -1):
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
    
    print(" ".join(map(str, dp)))

def test_multi_pack2():
    '''版本:改变遍历个数'''
    weight = [1, 3, 4]
    value = [15, 20, 30]
    nums = [2, 3, 2]
    bag_weight = 10

    dp = [0]*(bag_weight + 1)
    for i in range(len(weight)):
        for j in range(bag_weight, weight[i] - 1, -1):
            # 以上是01背包,加上遍历个数
            for k in range(1, nums[i] + 1):
                if j - k*weight[i] >= 0:
                    dp[j] = max(dp[j], dp[j - k*weight[i]] + k*value[i])

    print(" ".join(map(str, dp)))


if __name__ == '__main__':
    test_multi_pack1()
    test_multi_pack2()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值