日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

九十、动态规划系列背包问题之多重背包

發布時間:2024/10/8 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 九十、动态规划系列背包问题之多重背包 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

@Author:Runsen

曾幾何時,才記得自己還是大一軍訓的菜鳥,帶著 迷茫和憧憬踏入大學,踏入化工學院,卻踏入這個行業,殊不知歲月是最高明的小偷,偷走時間,帶走青春,一點線索也不留。大學的玩命學習,一轉眼,就大四了,一不小心就成了學校最老的學長!

前面已經介紹完了01背包和完全背包,今天介紹最后一種背包問題——多重背包。

題目是這樣的:來源:https://www.acwing.com/problem/content/4/

NNN 種物品和一個容量是VVV 的背包。

iii 種物品最多有 sisisi件,每件體積是ViViVi,價值是 wiwiwi

求解將哪些物品裝入背包,可使物品體積總和不超過背包容量,且價值總和最大。
輸出最大價值。

輸入格式
第一行兩個整數,NNNVVV,用空格隔開,分別表示物品種數和背包容積。

接下來有 NNN 行,每行三個整數 ViViVi,wiwiwi,sisisi,用空格隔開,分別表示第 iii 種物品的體積、價值和數量。

輸出格式
輸出一個整數,表示最大價值。

輸入樣例 4 5 1 2 3 # 體積、價值和數量 2 4 1 3 4 3 4 5 2 輸出樣例: 10

狀態表示:dp[j]

  • 集合:當前價值j的最大值
  • 屬性:最大值
  • 多重背包問題的思路跟完全背包的思路非常類似,只是取值是有限制的,因為每件物品的數量是有限制的,狀態轉移方程為:dp [j] = max(dp [j], dp [j - k*b] + k*w) 這里的b和w指的是當前遍歷的體積和價值。

    這里一維動態規劃和01背包基一樣,就是多了一個k的循環,具體的查看下面代碼。

    n, v = map(int, input().split())dp = [0 for _ in range(v+1)]for i in range(n):b, w, s = map(int, input().split())for j in range(v, -1, -1):k = 1while k <= s and j >= k * b:dp [j] = max(dp [j], dp [j - k*b] + k*w)k += 1 print(dp[v])

    除了上面的方法,還有用最原始的方法,將多個同一物品轉化成不同物品,再用01背包求解

    n,v = map(int, input().split()) goods = [] for i in range(n):goods.append([int(i) for i in input().split()])new_goods = []for i in range(n):for j in range(goods[i][2]):new_goods.append(goods[i][0:2])goods = new_goods n = len(goods)dp = [0 for i in range(v+1)]for i in range(n):# 01背包倒序for j in range(v,-1,-1):if j>= goods[i][0]:dp[j] = max(dp[j], dp[j - goods[i][0]] + goods[i][1]) print(dp[-1])

    關于多重背包問題中的二進制解法,Runsen下一篇再寫。如今就是體現自己的實力的時候了。Leetcode刷起來。

    Leetcode 面試題 17.16. 按摩師

    `一個有名的按摩師會收到源源不斷的預約請求,每個預約都可以選擇接或不接。在每次預約服務之間要有休息時間,因此她不能接受相鄰的預約。給定一個預約請求序列,替按摩師找到最優的預約集合(總預約時間最長),返回總的分鐘數。

    注意:本題相對原題稍作改動

    示例 1:

    輸入: [1,2,3,1]
    輸出: 4
    解釋: 選擇 1 號預約和 3 號預約,總時長 = 1 + 3 = 4。
    示例 2:

    輸入: [2,7,9,3,1]
    輸出: 12
    解釋: 選擇 1 號預約、 3 號預約和 5 號預約,總時長 = 2 + 9 + 1 = 12。

    題目,其實就是不連續最大子序列。

    每個預約都可以選擇接或不接來做出思考,每次都有兩種選擇,那么就是狀態轉移方程:
    dp[k]=max(dp[k?1],nums[k]+dp[k?2])dp[k] = max(dp[k - 1], nums[k ] + dp[k - 2])dp[k]=max(dp[k?1],nums[k]+dp[k?2])

    class Solution:def massage(self, nums: List[int]) -> int:if len(nums) == 0:return 0# 求最值用0 dp = [0] * (len(nums))dp[0] = nums[0]for k in range(1,len(nums)):dp[k] = max(dp[k - 1], nums[k] + dp[k - 2])return dp[-1]

    Leetcode 面試題 08.11. 硬幣

    硬幣。給定數量不限的硬幣,幣值為25分、10分、5分和1分,編寫代碼計算n分有幾種表示法。(結果可能會很大,你需要將結果模上1000000007)

    示例1:

    輸入: n = 5
    輸出:2
    解釋: 有兩種方式可以湊成總金額:
    5=5
    5=1+1+1+1+1
    示例2:

    輸入: n = 10
    輸出:4
    解釋: 有四種方式可以湊成總金額:
    10=10
    10=5+5
    10=5+1+1+1+1+1
    10=1+1+1+1+1+1+1+1+1+1

    class Solution:def waysToChange(self, n: int) -> int:# 不就是一個零錢對換問題 的完全背包問題? 這里需要將結果模上 10**9 + 7# 求最大值dp = [0] * (n+1)# f(11) = min(f(10),f(9),f(6)) + 1dp[0] = 1for i in [1,5,25,10]:for j in range(i, n + 1):dp[j] += dp[j - i]return dp[-1] % 1000000007

    總結

    以上是生活随笔為你收集整理的九十、动态规划系列背包问题之多重背包的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。