Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[pull] main from itcharge:main #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
pull merged 18 commits into AlgorithmAndLeetCode:main from itcharge:main
Mar 29, 2023
Merged
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d191c89
Update Pack-ProblemVariants.py
itcharge Mar 28, 2023
d122b5b
Update 04.Knapsack-Problem-04.md
itcharge Mar 28, 2023
6c94cc0
Update Pack-ProblemVariants.py
itcharge Mar 28, 2023
6782bc4
Create Pack-MixedPack.py
itcharge Mar 28, 2023
e7d5a47
Update 04.Knapsack-Problem-04.md
itcharge Mar 28, 2023
626f88f
Create 05.Knapsack-Problem-05.md
itcharge Mar 28, 2023
91e382d
Create 06.Knapsack-Problem-List.md
itcharge Mar 28, 2023
50a1b03
Update 01.Knapsack-Problem-01.md
itcharge Mar 28, 2023
e55f633
Update 02.Knapsack-Problem-02.md
itcharge Mar 28, 2023
d758676
Update 03.Knapsack-Problem-03.md
itcharge Mar 28, 2023
b280e74
Update 04.Knapsack-Problem-04.md
itcharge Mar 28, 2023
1586ce9
Update 05.Knapsack-Problem-05.md
itcharge Mar 28, 2023
7ff6bf9
Delete 05.Knapsack-Problem-List.md
itcharge Mar 28, 2023
f331c22
Update Pack-ProblemVariants.py
itcharge Mar 28, 2023
9892e44
Update 01.Knapsack-Problem-01.md
itcharge Mar 28, 2023
294e477
Update Categories-List.md
itcharge Mar 29, 2023
b0afdc1
Update README-Catalogue-List.md
itcharge Mar 29, 2023
21b9e37
更新目录列表链接
itcharge Mar 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update Pack-ProblemVariants.py
  • Loading branch information
itcharge committed Mar 28, 2023
commit f331c228db161b629db53d804e4e7e1e65ec6da8
173 changes: 149 additions & 24 deletions Templates/10.Dynamic-Programming/Pack-ProblemVariants.py
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
class Solution:

# 0-1 背包问题相关变种
# 1. 求恰好装满背包的最大价值

# 0-1 背包问题 求恰好装满背包的最大价值
def zeroOnePackJustFillUp(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [float('-inf') for _ in range(W + 1)]
dp[0] = 0

# 枚举前 i 种物品
for i in range(1, size + 1):
# 逆序枚举背包装载重量(避免状态值错误)
for w in range(W, weight[i - 1] - 1, -1):
# dp[w] 取「前 i - 1 件物品装入载重为 w 的背包中的最大价值」与「前 i - 1 件物品装入载重为 w - weight[i - 1] 的背包中,再装入第 i - 1 物品所得的最大价值」两者中的最大值
dp[w] = max(dp[w], dp[w - weight[i - 1]] + value[i - 1])

if dp[W] == float('-inf'):
return -1
return dp[W]

# 0-1 背包问题求方案总数
# 完全背包问题 求恰好装满背包的最大价值
def completePackJustFillUp(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [float('-inf') for _ in range(W + 1)]
dp[0] = 0

# 枚举前 i 种物品
for i in range(1, size + 1):
# 正序枚举背包装载重量
for w in range(weight[i - 1], W + 1):
# dp[w] 取「前 i - 1 件物品装入载重为 w 的背包中的最大价值」与「前 i - 1 件物品装入载重为 w - weight[i - 1] 的背包中,再装入第 i - 1 物品所得的最大价值」两者中的最大值
dp[w] = max(dp[w], dp[w - weight[i - 1]] + value[i - 1])

if dp[W] == float('-inf'):
return -1
return dp[W]


# 2. 求方案总数

# 0-1 背包问题 求方案总数
def zeroOnePackNumbers(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [0 for _ in range(W + 1)]
Expand All @@ -17,7 +53,25 @@ def zeroOnePackNumbers(self, weight: [int], value: [int], W: int):

return dp[W]

# 0-1 背包问题求最优方案数 思路 1
# 完全背包问题求方案总数
def completePackNumbers(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [0 for _ in range(W + 1)]
dp[0] = 1

# 枚举前 i 种物品
for i in range(1, size + 1):
# 正序枚举背包装载重量
for w in range(weight[i - 1], W + 1):
# dp[w] = 前 i - 1 种物品装入载重为 w 的背包中的方案数 + 前 i 种物品装入载重为 w - weight[i - 1] 的背包中,再装入 1 件第 i - 1 种物品的方案数
dp[w] = dp[w] + dp[w - weight[i - 1]]

return dp[W]


# 3. 求最优方案数

# 0-1 背包问题 求最优方案数 思路 1
def zeroOnePackMaxProfitNumbers1(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [[0 for _ in range(W + 1)] for _ in range(size + 1)]
Expand Down Expand Up @@ -73,25 +127,6 @@ def zeroOnePackMaxProfitNumbers2(self, weight: [int], value: [int], W: int):

return op[W]


# 完全背包问题相关变种

# 完全背包问题求方案总数
def completePackNumbers(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [0 for _ in range(W + 1)]
dp[0] = 1

# 枚举前 i 种物品
for i in range(1, size + 1):
# 正序枚举背包装载重量
for w in range(weight[i - 1], W + 1):
# dp[w] = 前 i - 1 种物品装入载重为 w 的背包中的方案数 + 前 i 种物品装入载重为 w - weight[i - 1] 的背包中,再装入 1 件第 i - 1 种物品的方案数
dp[w] = dp[w] + dp[w - weight[i - 1]]

return dp[W]


# 完全背包问题求最优方案数 思路 1
def completePackMaxProfitNumbers1(self, weight: [int], value: [int], W: int):
size = len(weight)
Expand Down Expand Up @@ -146,4 +181,94 @@ def completePackMaxProfitNumbers2(self, weight: [int], value: [int], W: int):
# 方案数 = 不使用第 i - 1 种物品的方案数 + 使用 1 件第 i - 1 种物品的方案数
op[w] = op[w] + op[w - weight[i - 1]]

return dp[size][W]
return dp[size][W]


# 4. 求具体方案

# 0-1 背包问题求具体方案
def zeroOnePackPrintPath(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [[0 for _ in range(W + 1)] for _ in range(size + 1)]
path = [[False for _ in range(W + 1)] for _ in range(size + 1)]

# 枚举前 i 种物品
for i in range(1, size + 1):
# 枚举背包装载重量
for w in range(W + 1):
# 第 i - 1 件物品装不下
if w < weight[i - 1]:
# dp[i][w] 取「前 i - 1 种物品装入载重为 w 的背包中的最大价值」
dp[i][w] = dp[i - 1][w]
path[i][w] = False
else:
# 选择第 i - 1 件物品获得价值更高
if dp[i - 1][w] < dp[i - 1][w - weight[i - 1]] + value[i - 1]:
dp[i][w] = dp[i - 1][w - weight[i - 1]] + value[i - 1]
# 取状态转移式第二项:在之前方案基础上添加了第 i - 1 件物品
path[i][w] = True
# 两种方式获得价格相等
elif dp[i - 1][w] == dp[i - 1][w - weight[i - 1]] + value[i - 1]:
dp[i][w] = dp[i - 1][w]
# 取状态转移式第二项:尽量使用第 i - 1 件物品
path[i][w] = True
# 不选择第 i - 1 件物品获得价值最高
else:
dp[i][w] = dp[i - 1][w]
# 取状态转移式第一项:不选择第 i - 1 件物品
path[i][w] = False

res = []
i, w = size, W
while i >= 1 and w >= 0:
if path[i][w]:
res.append(str(i - 1))
w -= weight[i - 1]
i -= 1

return " ".join(res[::-1])

# 0-1 背包问题求具体方案,要求最小序输出
def zeroOnePackPrintPathMinOrder(self, weight: [int], value: [int], W: int):
size = len(weight)
dp = [[0 for _ in range(W + 1)] for _ in range(size + 1)]
path = [[False for _ in range(W + 1)] for _ in range(size + 1)]

weight.reverse()
value.reverse()

# 枚举前 i 种物品
for i in range(1, size + 1):
# 枚举背包装载重量
for w in range(W + 1):
# 第 i - 1 件物品装不下
if w < weight[i - 1]:
# dp[i][w] 取「前 i - 1 种物品装入载重为 w 的背包中的最大价值」
dp[i][w] = dp[i - 1][w]
path[i][w] = False
else:
# 选择第 i - 1 件物品获得价值更高
if dp[i - 1][w] < dp[i - 1][w - weight[i - 1]] + value[i - 1]:
dp[i][w] = dp[i - 1][w - weight[i - 1]] + value[i - 1]
# 取状态转移式第二项:在之前方案基础上添加了第 i - 1 件物品
path[i][w] = True
# 两种方式获得价格相等
elif dp[i - 1][w] == dp[i - 1][w - weight[i - 1]] + value[i - 1]:
dp[i][w] = dp[i - 1][w]
# 取状态转移式第二项:尽量使用第 i - 1 件物品
path[i][w] = True
# 不选择第 i - 1 件物品获得价值最高
else:
dp[i][w] = dp[i - 1][w]
# 取状态转移式第一项:不选择第 i - 1 件物品
path[i][w] = False

res = []
i, w = size, W
while i >= 1 and w >= 0:
if path[i][w]:
res.append(str(size - i))
w -= weight[i - 1]
i -= 1

return " ".join(res)

AltStyle によって変換されたページ (->オリジナル) /