【leetcode】揹包問題彙總
轉自:https://blog.csdn.net/u013166817/article/details/85449218
版權宣告:轉載請註明 https://blog.csdn.net/u013166817/article/details/85449218
詳細解析參考“揹包九講”:https://github.com/tianyicui/pack
目錄
1. 揹包問題 I —— 0-1揹包無價值
2. 揹包問題II —— 0-1揹包有價值
3. 揹包問題III —— 完全揹包問題
小結1
4. 揹包問題IV / V —— 求方案數
5. 揹包問題VII —— 多重揹包問題
6. 多重揹包可行性解
7. 換零錢問題
1. 揹包問題 I —— 0-1揹包無價值
0-1揹包問題,無價值:https://www.lintcode.com/problem/backpack/description
問題描述:Given n items with size Ai, an integer m denotes the size of a backpack. How full you can fill this backpack?
解析:
遞推公式:
:前i個物品放入容量為j的揹包的最大重量;
:放入第i個時的重量;
:不放第i個時的重量;
第一層迴圈 i:0~n
第二層迴圈 j:m ~ Ai,倒序是因為每個物品只能用一次。
可簡化成一位陣列。
class Solution:
"""
@param m: An integer m denotes the size of a backpack
@param A: Given n items with size A[i]
@return: The maximum size
"""
def backPack(self, m, A):
n = len(A)
if n <= 0 or m <= 0:
return 0
dp = [0 for _ in range(m+1)]
for i in range(n):
for j in range(m,A[i]-1,-1):
dp[j] = max(dp[j-A[i]] + A[i], dp[j])
return dp[-1]
2. 揹包問題II —— 0-1揹包有價值
0-1揹包問題有價值:https://www.lintcode.com/problem/backpack-ii/
問題描述:
Given n items with size Ai and value Vi, and a backpack with size m. What's the maximum value can you put into the backpack?
Example:
Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 9.
思路:同上
class Solution:
"""
@param m: An integer m denotes the size of a backpack
@param A: Given n items with size A[i]
@param V: Given n items with value V[i]
@return: The maximum value
"""
def backPackII(self, m, A, V):
# write your code here
n = len(A)
if m <= 0 or n <= 0:
return 0
dp = [0 for _ in range(m + 1)]
for i in range(n):
for j in range(m,A[i]-1,-1):
dp[j] = max(dp[j-A[i]]+V[i], dp[j])
return dp[m]
3. 揹包問題III —— 完全揹包問題
完全揹包問題,有價值無限個數:https://www.lintcode.com/problem/backpack-iii/description
問題描述:
Given n kind of items with size Ai and value Vi( each item has an infinite number available) and a backpack with size m. What's the maximum value can you put into the backpack?
Example:
Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 15.
思路:
遞推公式:
:同理;
:放入第i個物品時,不管上一次放沒放入過該物品;
:不放入第i個物品時;
第一層迴圈i:0~n
第二層迴圈j:Ci~m,正向,因為不用顧忌每個物品只能放一次。
class Solution:
"""
@param A: an integer array
@param V: an integer array
@param m: An integer
@return: an array
"""
def backPackIII(self, A, V, m):
# write your code here
n = len(A)
if n <= 0 or m <= 0:
return 0
dp = [0 for _ in range(m+1)]
for i in range(n):
for j in range(A[i], m+1):
dp[j] = max(dp[j-A[i]] + V[i], dp[j])
return dp[-1]
小結1
0-1揹包問題 vs 完全揹包問題,實質性區別在於第二層迴圈一個是倒序,一個是正序:
4. 揹包問題IV / V —— 求方案數
0-1 揹包問題,返回方案數:https://www.lintcode.com/problem/backpack-v/description
完全揹包問題,返回方案數:https://www.lintcode.com/problem/backpack-iv/description
以完全揹包問題為例:
Given n items with size nums[i] which an integer array and all positive numbers, no duplicates. An integer target denotes the size of a backpack. Find the number of possible fill the backpack.
Each item may be chosen unlimited number of times
Example:
Given candidate items [2,3,6,7] and target 7,
A solution set is:
[7]
[2, 2, 3]
return 2
解析:
將完全揹包問題裡面的max改為sum,且初始化時將dp[0] 設為1;
class Solution:
"""
@param nums: an integer array and all positive numbers, no duplicates
@param target: An integer
@return: An integer
"""
def backPackIV(self, nums, target):
# write your code here
n = len(nums)
if n <= 0 or target < 0:
return 0
dp = [0 for _ in range(target+1)]
dp[0] = 1
for i in range(n):
for j in range(nums[i],target+1):
dp[j] = dp[j - nums[i]] + dp[j]
return dp[-1]
5. 揹包問題VII —— 多重揹包問題
多重揹包問題,每個物品有限個個數,求最大價值:https://www.lintcode.com/problem/backpack-vii/description
問題描述:
Assume that you have n yuan. There are many kinds of rice in the supermarket. Each kind of rice is bagged and must be purchased in the whole bag. Given the weight, price and quantity of each type of rice, find the maximum weight of rice that you can purchase.
Example:
Given:
n = 8
prices = [2,4]
weight = [100,100]
amounts = [4,2]
Return:400
基本思路:
假設有N類物品,每個物品有個,則可以轉換成 個0-1揹包問題。則時間複雜度為:,,V為揹包容量,M是每個物品的個數的集合。
進階思路:
可以將每類物品分成 個,每個對應一個新的價值和重量,然後轉化為個0-1 揹包問題,則時間複雜的降為:。
import math
class Solution:
"""
@param n: the money of you
@param prices: the price of rice[i]
@param weight: the weight of rice[i]
@param amounts: the amount of rice[i]
@return: the maximum weight
"""
def backPackVII(self, n, prices, weight, amounts):
#將每一類物品轉化為k個子物品,求得對應的價錢,重量,轉化成0-1揹包問題
#先生成新的物品集合
new_prices = []
new_weight = []
for i in range(len(amounts)):
k = int(math.log(amounts[i],2))+1
coefs = [2**i for i in range(k - 1)]
coefs.append(amounts[i] - 2**(k-1) + 1)
for item in coefs:
new_prices.append(item*prices[i])
new_weight.append(item*weight[i])
#0-1揹包問題
dp = [0 for _ in range(n+1)]
for i in range(len(new_prices)):
for j in range(n, new_prices[i]-1, -1):
dp[j] = max(dp[j-new_prices[i]] + new_weight[i], dp[j])
return dp[-1]
6. 多重揹包可行性解
多重揹包問題求可行性解的個數:https://www.lintcode.com/problem/backpack-viii/description
問題描述:
Give some coins of different value and their quantity. Find how many values which are in range 1 ~ n can these coins be combined
Example
Given:
n = 10
value = [1,2,4]
amount = [2,1,1]
Return: 8
They can combine all the values in 1 ~ 8
思路:
class Solution:
"""
@param n: the value from 1 - n
@param value: the value of coins
@param amount: the number of coins
@return: how many different value
"""
#多重揹包可行性問題 O(VN)
def backPackVIII(self, n, value, amount):
# write your code here
dp = [-1 for _ in range(n+1)]
dp[0] = 0
for i in range(len(value)):
for j in range(n+1):
if dp[j] >= 0:
dp[j] = amount[i]
else:
dp[j] = -1
for j in range(n-value[i]+1):
if dp[j] > 0:
dp[j+value[i]] = max(dp[j+value[i]], dp[j] - 1)
return n - dp.count(-1)
7. 換零錢問題
即完全揹包問題求解最小的使用個數。:https://www.lintcode.com/problem/coin-change/description
問題描述:
You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
Example:
Given coins = [1, 2, 5], amount = 11
return 3 (11 = 5 + 5 + 1)
Given coins = [2], amount = 3
return -1.
Notice:
You may assume that you have an infinite number of each kind of coin.
思路:完全揹包問題,轉換成最小組合數。
class Solution:
"""
@param coins: a list of integer
@param amount: a total amount of money amount
@return: the fewest number of coins that you need to make up
"""
def coinChange(self, coins, amount):
# write your code here
dp = [float('inf') for _ in range(amount+1)]
dp[0] = 0
for i in range(len(coins)):
for j in range(coins[i],amount+1):
dp[j] = min(dp[j-coins[i]] + 1, dp[j])
if dp[-1] < float('inf'):
return dp[-1]
else:
return -1
---------------------
作者:jrzhanged
來源:CSDN
原文:https://blog.csdn.net/u013166817/article/details/85449218
版權宣告:本文為博主原創文章,轉載請附上博文連結!
相關文章
- 揹包問題例題總結
- 揹包問題(01揹包與完全揹包)
- 揹包問題解題方法總結
- 揹包問題
- leetcode題解(0-1揹包問題)LeetCode
- ACM 揹包問題ACM
- 01揹包問題
- 揹包題型總結
- 揹包問題大合集
- 從【零錢兌換】問題看01揹包和完全揹包問題
- JavaScript中揹包問題(面試題)JavaScript面試題
- 模板問題:Knapsack (LeetCode: Coin Change)[揹包問題九講筆記]LeetCode筆記
- JavaScript 揹包問題詳解JavaScript
- 01揹包問題的解決
- 揹包問題----動態規劃動態規劃
- 【動態規劃】揹包問題動態規劃
- Java實現-揹包問題IJava
- Java實現-揹包問題IIJava
- Java實現-揹包問題VIJava
- 揹包問題的演算法演算法
- chapter12-2-揹包問題APT
- 二維費用揹包問題
- 揹包問題的一道經典問題
- LeetCode 解題彙總LeetCode
- 動態規劃 01揹包問題動態規劃
- 【動態規劃】01揹包問題動態規劃
- 動態規劃-01揹包問題動態規劃
- 動態規劃篇——揹包問題動態規劃
- 動態規劃--01揹包問題動態規劃
- 【資料結構與演算法】揹包問題總結梳理資料結構演算法
- 資料結構和演算法面試題系列—揹包問題總結資料結構演算法面試題
- 【動態規劃】01揹包問題【續】動態規劃
- 【演算法】0-1揹包問題演算法
- Leetcode刷題系列彙總LeetCode
- CSS問題彙總CSS
- RecyclerView問題彙總View
- Redis問題彙總Redis
- nginx 問題彙總Nginx