【23/10/9】01背包

【23/10/9】01背包

题目

在这里插入图片描述

import sys

n, v = map(int, sys.stdin.readline().strip().split())
line = sys.stdin.readline().strip()
line = list(map(int, line.split()))
dp = [line[1] if i == line[0] else -float("inf") for i in range(v + 1)]
dp[0] = 0
for _ in range(n - 1):
    line = sys.stdin.readline().strip()
    line = list(map(int, line.split()))
    for i in range(v, line[0] - 1, -1):
        temp = line[1] + dp[i - line[0]]
        if temp > dp[i]:
            dp[i] = temp


print(max(dp))
print(dp[-1] if dp[-1] > 0 else 0)

笔记

sys.stdin.readline().strip().split()

1、sys.stdin.readline() 从标准输入(stdin)中读取一行文本。sys.stdin 是Python的sys模块中的一个标准输入对象,readline() 方法用于读取一行文本。

2、strip() 方法用于去除读取到的文本行末尾的换行符和空格等空白字符。这样可以确保得到干净的文本行。

3、split() 方法将经过strip()处理的文本行拆分成一个字符串列表,拆分的标志默认是空格字符(空格、制表符、换行符等)。这样,你可以得到一个包含多个值的列表,每个值对应原始文本行中的一个部分。

line = list(map(int, line.split()))

1、sys.stdin.readline().strip():从标准输入(stdin)读取一行文本,并使用 .strip() 方法去除行首和行尾的空白字符(如空格和换行符)。

2、.split():使用默认的分隔符(空格)将文本行分割成一个字符串列表。例如,如果文本行是 “5 10”,使用 .split() 后就得到 [“5”, “10”] 这样的字符串列表。

3、map(int, …):map() 函数用于将列表中的每个元素都应用一个函数,这里的函数是 int,用于将字符串转换为整数。所以,map(int, [“5”, “10”]) 将返回一个整数列表 [5, 10]。

4、line = list(…):最后,将转换后的整数列表存储在名为 line 的变量中,以供后续使用。

这行代码的主要作用是将从标准输入读取的一行包含空格分隔的整数数据转换为一个整数列表,方便后续代码对这些数据进行操作和处理。这种操作在处理输入数据时非常常见,特别是在需要将输入数据解析为整数或其他数据类型时。

dp = [line[1] if i == line[0] else -float("inf") for i in range(v + 1)]

1、dp 是一个列表,用于存储动态规划中的状态值。

2、for i in range(v + 1) 是一个循环,遍历从0到v的整数。

3、line[1] if i == line[0] else -float(“inf”) 是一个条件表达式。如果i等于line[0](line[0]可能是某种条件的值),则将line[1]赋给dp[i],否则将负无穷大(-float(“inf”))赋给dp[i]。

这行代码的目的是初始化dp列表,将特定的值(line[1])赋给某个特定的索引位置(line[0]),同时将负无穷大赋给其他索引位置。这通常用于动态规划中的初始状态设置,以确保状态转移过程正确执行。

要使用这个dp列表进行状态转移或其他操作,通常需要在此基础上进行进一步的更新和计算。

for _ in range(n - 1):
    line = sys.stdin.readline().strip()
    line = list(map(int, line.split()))
    for i in range(v, line[0] - 1, -1):
        temp = line[1] + dp[i - line[0]]
        if temp > dp[i]:
            dp[i] = temp

1、for _ in range(n - 1)::这是一个循环,用于遍历剩余的物品。n 表示物品的总数量,减去1是因为第一个物品已经在初始化阶段处理过了。

2、line = sys.stdin.readline().strip():从标准输入读取一行文本,并去除首尾的空白字符。

3、line = list(map(int, line.split())):将读取到的文本行分割成整数,并存储在名为 line 的列表中。这个列表包含了当前物品的体积和价值。

4、for i in range(v, line[0] - 1, -1)::这是一个内部循环,从背包容量 v 开始递减到当前物品的体积 line[0](包括 line[0])。这个内部循环是为了处理背包容量递减时的状态转移。

5、temp = line[1] + dp[i - line[0]]:计算将当前物品放入背包后的总价值 temp。具体计算方式是将当前物品的价值 line[1] 加上剩余容量 i - line[0] 时的最大总价值 dp[i - line[0]]。这里利用了动态规划中的状态转移。

6、if temp > dp[i]::比较计算得到的总价值 temp 与当前容量 i 下的最大总价值 dp[i]。如果 temp 大于 dp[i],则表示将当前物品放入背包可以获得更大的总价值,因此进行更新。

7、dp[i] = temp:如果条件满足,将 dp[i] 更新为 temp,表示在当前容量 i 下的最大总价值。

这段代码的核心功能是通过状态转移更新 dp 数组,以计算在不同背包容量下的最大总价值。通过遍历每个物品和每个容量,依次计算并更新状态,最终得到的 dp 数组中的最大值即为问题的答案,表示在给定容量下能够装入的物品的最大总价值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值