中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

大站網(wǎng)站建設(shè)百度自動(dòng)優(yōu)化

大站網(wǎng)站建設(shè),百度自動(dòng)優(yōu)化,菜鳥教程網(wǎng)站是怎么做的,網(wǎng)頁小游戲在線目錄 0、背包問題分類 1、 0/1背包簡化版 【代碼】 2、0/ 1背包的方案數(shù) 【思路】 【做法】 【代碼】 空間優(yōu)化1:交替滾動(dòng) 空間優(yōu)化2:自我滾動(dòng) 3、完全背包 【思路】 【代碼】 4、分組背包 核心代碼 5、多重背包 多重背包解題思路1:轉(zhuǎn)化…

目錄

0、背包問題分類

1、?0/1背包簡化版

【代碼】

2、0/ 1背包的方案數(shù)

【思路】

【做法】

【代碼】

空間優(yōu)化1:交替滾動(dòng)

空間優(yōu)化2:自我滾動(dòng)

?3、完全背包

【思路】

【代碼】

4、分組背包?

核心代碼

5、多重背包

多重背包解題思路1:轉(zhuǎn)化為0/1背包

多重背包解題思路2:直接DP

?????????核心代碼

多重背包解題思路3:二進(jìn)制拆分優(yōu)化

拆分要點(diǎn)

多重背包解題思路4:單調(diào)隊(duì)列

模板題

【代碼】


0、背包問題分類

背包問題可分為0/1背包簡化版,背包方案數(shù),完全背包,分組背包,多重背包

1、?0/1背包簡化版

0/1背包的簡化版:不管物品的價(jià)值。把體積看成最優(yōu)化目標(biāo):最大化體積。?

裝箱問題????????lanqi ao0J題號(hào)763

題目描述

有一個(gè)箱子容量為?V(正整數(shù),0≤V≤20000),同時(shí)有?n?個(gè)物品(0≤n≤30),每個(gè)物品有一個(gè)體積(正整數(shù))。

要求?n?個(gè)物品中,任取若干個(gè)裝入箱內(nèi),使箱子的剩余空間為最小。

輸入描述

輸入第一行,一個(gè)整數(shù),表示箱子容量。

第二行,一個(gè)整數(shù)?n,表示有?n?個(gè)物品。

接下來?n?行,分別表示這?n?個(gè)物品的各自體積。

輸出描述

輸出一行,表示箱子剩余空間。

輸入輸出樣例

輸入

24
6
8
3
12
7
9
7

輸出

0

0/1背包的簡化版,不管物品的價(jià)格。把體積(不是價(jià)格)看成最優(yōu)化目標(biāo):最大化體積。

【代碼】

dp = [0]*20010
V = int(input())# 容量
n = int(input())# 物品數(shù)
c = [0]*40      # 存每個(gè)物品體積
# 讀入每個(gè)物體的體積
for i in range(1, n+1): c[i]=int(input ())
# 自我滾動(dòng)
for i in range (1, n+1) :for j in range (V, c[i]-1,-1):dp[j] = max(dp[j],dp[j-c[i]]+c[i])
print(V-dp[V]) # 剩余最小容量 = 容量 - 物品最大體積

2、0/ 1背包的方案數(shù)

2022年屆國賽,填空題,langiao0J題號(hào)2186

問題描述

將 2022 拆分成 10 個(gè)互不相同的正整數(shù)之和, 總共有多少種拆分方法?

注意交換順序視為同一種方法, 例如 2022=1000+1022?和?2022=1022+1000?就視為同一種方法。

答案提交

這是一道結(jié)果填空的題, 你只需要算出結(jié)果后提交即可。本題的結(jié)果為一 個(gè)整數(shù), 在提交答案時(shí)只填寫這個(gè)整數(shù), 填寫多余的內(nèi)容將無法得分。

【思路】

  • 題目求10個(gè)數(shù)的組合情況,這十個(gè)數(shù)相加等于2022。因?yàn)槭翘羁疹}可以不管運(yùn)行時(shí)間,看起來可以用暴力for循環(huán)10次,加上剪枝。然而暴力的時(shí)間極長,因?yàn)榇鸢甘?379187662194355221。
  • 建模:這一題其實(shí)是0/1背包背包容量為2022,物品體積為1~2022,往背包中裝10個(gè)物品,要求總體積為2022,問一共有多少種方案。
  • 與標(biāo)準(zhǔn)背包的區(qū)別:是求方案總數(shù)。

?【做法】

  • 定義dp[ ][ ][ ]: dp[i][i][k]表示數(shù)字1~i取j個(gè),容量為k的方案數(shù)
  • 下面的分析沿用標(biāo)準(zhǔn)0/1背包的分析方法。
  • 從i-1擴(kuò)展到i,分兩種情況:

????????(1) k>i:數(shù)i可以要,也可以不要。
? ? ? ? ? ? ?要i:? ?從1~i-1中取j-1個(gè)數(shù),再取i,等價(jià)于dp[i-1][j-1][k-i]。

? ? ? ? ? ? ?不要i:從1~i-1中取j個(gè)數(shù),等價(jià)于dp[i-1][i][k]
?????????????合起來(要和不要的總方案數(shù)): dp[i][i][k] = dp[i-1][i][k] + dp[i-1][j-1][k-i]
????????( 2) k<i:由于數(shù)i比總和k還大,顯然i不能用。有: dp[i][i][k]= dp[i-1][ji][k]

【代碼】

空間優(yōu)化1:交替滾動(dòng)

dp = [[[0]*2222 for i in range(11)] for j in range(2222)]   # 比題目要求的數(shù)據(jù)范圍大一點(diǎn)
for i in range(0,2023): dp[i][0][0]=1 # 初始化:遞推條件的初始值,不選也是一種方案
for i in range(1,2023):for j in range(1,11):for k in range(1,2023):if k<i: dp[i][j][k] = dp[i-1][j][k]else:dp[i][j][k] = dp[i-1][j][k]+dp[i-1][j-1][k-i]
print(dp[2022][10][2022])

空間優(yōu)化2:自我滾動(dòng)

dp = [[0]*2222 for i in range(11)]
dp[0][0] = 1    #特別注意這個(gè)初始化
for i in range(1,2023):for j in range (10,0,-1):    # 10個(gè)數(shù)for k in range(i,2023):  # k>=idp[j][k] += dp[j-1][k-i]
print(dp[10][2022])

?3、完全背包

  • 特點(diǎn):每種物品有無窮多個(gè)?

小明的背包2lanqiao0J題號(hào)1175

題目描述

小明有一個(gè)容量為?V?的背包。

這天他去商場(chǎng)購物,商場(chǎng)一共有?N?種物品,第?i?種物品的體積為 wi?,價(jià)值為?vi?,每種物品都有無限多個(gè)

小明想知道在購買的物品總體積不超過?V?的情況下所能獲得的最大價(jià)值為多少,請(qǐng)你幫他算算。

輸入描述

輸入第?1?行包含兩個(gè)正整數(shù) N,V,表示商場(chǎng)物品的數(shù)量和小明的背包容量。

第 2~N+1?行包含?2?個(gè)正整數(shù) w,v,表示物品的體積和價(jià)值。

1≤N≤10^3,1≤V≤10^3,1≤wi?,vi?≤10^3。

輸出描述

輸出一行整數(shù)表示小明所能獲得的最大價(jià)值。

輸入輸出樣例

輸入

5 20
1 6
2 5
3 8
5 15
3 3 

輸出

120

【思路】

和0/1背包類似。0/1背包的每種物品只有1件,完全背包的每種物品有無窮多件,第i種可以裝0件、1件、2件、.....、C//c_i件。
做法:定義dp[i][j]:把前i種物品(從第1種到第i種)裝入容量為j的背包中獲得的最大價(jià)值。把每個(gè)dp[i][j]都看成一個(gè)背包:背包容量為j,裝1~i這些物品。最后得到的dp[N][C]就是問題的答案:把N種物品裝進(jìn)容量C的背包的最大價(jià)值。
區(qū)別:0/1背包問題中,每個(gè)物品只有拿與不拿兩種;而完全背包問題,需要考慮拿幾個(gè)

【代碼】

完全背包的代碼和0/1背包的代碼相似,只多了一個(gè)k循環(huán),用來遍歷每種物品拿幾個(gè)。

def solve(n,C) :for i in range (1, n+1):for j in range (0,C+1):dp[i][j] = dp[i - 1][j]      # 初始化為都不裝的情況for k in range(1,j//c[i]+1): # 可以拿1~j//c[i]個(gè)該物品  k*c[i]<=j #在容量為j的背包中放k個(gè)dp[i][j] = max(dp[i][j],dp[i - 1][j - k * c[i]] +k * w[i])return dp[n][C]N = 3011
dp = [[0]*N for j in range(N)]
w =[0]*N; c = [0]*N
n,C = map(int,input().split())
for i in range(1, n+1):c[i], w[i] = map(int,input ().split())  # 每個(gè)物品的體積和價(jià)值
print(solve(n,C))

也可以不需要初始化條件,但下面要從0個(gè)該物品開始遍歷,這樣寫代碼更加簡潔,但時(shí)間復(fù)雜度高了一點(diǎn),代碼如下:

def solve(n,C) :for i in range (1, n+1):for j in range (0,C+1):dp[i][j] = dp[i - 1][j]      # 初始化為都不裝的情況for k in range(1,j//c[i]+1): # 可以拿1~j//c[i]個(gè)該物品  k*c[i]<=j #在容量為j的背包中放k個(gè)dp[i][j] = max(dp[i][j],dp[i - 1][j - k * c[i]] +k * w[i])return dp[n][C]N = 3011
dp = [[0]*N for j in range(N)]
w =[0]*N; c = [0]*N
n,C = map(int,input().split())
for i in range(1, n+1):c[i], w[i] = map(int,input ().split())  # 每個(gè)物品的體積和價(jià)值
print(solve(n,C))

4、分組背包?

?分組背包問題:

  • 有一些物品,把物品分為n組,其中第i組第k個(gè)物品體積是c[i][k],價(jià)值是w[i][k];
  • 每組內(nèi)的物品沖突,每組內(nèi)最多只能選出一個(gè)物品;
  • 給定一個(gè)容量為C的背包,問如何選物品,使得裝進(jìn)背包的物品的總價(jià)值最大。

解題思路與0/1背包相似。

  • 0/1背包dp[i][j]:把前i個(gè)物品(從第1個(gè)到第i個(gè))裝入容量為j的背包中獲得的最大價(jià)值。
  • 分組背包dp[i][j]:把前i組物品裝進(jìn)容量j的背包(每組最多選一個(gè)物品),可獲得的最大價(jià)值。
  • 狀態(tài)轉(zhuǎn)移方程:
    ? ? ? ? ? ? ? ? ? ? ? ? ?dp[i][j] = max {dp[i-1][j],dp[i-1][j-c[i][k]] + w[i][k]}? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? dp[i-1][j]表示第i組不選物品,dp[i-1][j-c[i][k]]表示第i組選第k個(gè)物品
  • 求解方程需要做i、j、k的三重循環(huán)。

核心代碼:

狀態(tài)轉(zhuǎn)移方程:dp[i][j] = max {dp[i-1][j], dp[i-1][j-c[i][k]] + w[i][k]},用滾動(dòng)數(shù)組,變?yōu)?dp[j] = max {dp[j],dp[j-c[i][k]]+ w[i][k]}

dp = [0] * N
for i in range(1, n + 1):       # 遍歷每個(gè)組for j in range(C, -1, -1):  # 枚舉容量for k in range(1, C + 1):  # 用k枚舉第i組的所有物品if j >= c[i][k]:       # 第k個(gè)物品能裝進(jìn)容量j的背包dp[j] = max(dp[j], dp[j - c[i][k]] + w[i][k])  # 第i組第k個(gè)
print(dp[C])

5、多重背包

多重背包問題:

  • 給定n種物品和一個(gè)背包,第i種物品的體積是ci,價(jià)值為wi,并且有mi個(gè),背包的總?cè)萘繛镃。
  • 如何選擇裝入背包的物品,使得裝入背包中的物品的總價(jià)值最大?
  • 與完全背包的區(qū)別:完全背包是每種物品都有無限多個(gè),而多重背包是有限個(gè)

多重背包解題思路1:轉(zhuǎn)化為0/1背包

  • 轉(zhuǎn)換為0/1背包問題。
  • 把相同的m_i個(gè)第i種物品看成獨(dú)立的m_i個(gè),總共\sum_{i=1}^{n}m_i個(gè)物品,。
  • 然后按0/1背包求解,復(fù)雜度O(C*\sum_{i=1}^{n}m_i)

多重背包解題思路2:直接DP

  • 定義狀態(tài)dpli][j]:表示把前i個(gè)物品裝進(jìn)容量j的背包,能裝進(jìn)背包的最大價(jià)值。
  • 第i個(gè)物品分為裝或不裝兩種情況,狀態(tài)轉(zhuǎn)移方程:

????????????????????????????????dp[i][j] = max {dp[i-1][j],dp[i-1][j-k*c[i]] +k*w[i]}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1 ≤k ≤min{m[i], j/c[i]}? ? ? ? ? ? ?# k不能超過?m_i個(gè)和最大容量個(gè)數(shù)的最小值

  • 直接寫i、j、k三重循環(huán),復(fù)雜度和第一種思路的復(fù)雜度一樣。
  • 對(duì)比完全背包:1≤k ≤ j/c[i]

核心代碼:?

????????狀態(tài)轉(zhuǎn)移方程:dp[i][j] = max {dp[i-1][j], dp[i-1][j-k*c[i]]+ k*w[i]},用滾動(dòng)數(shù)組,變?yōu)?dp[j] = max{dp[j],dp[j-k*c[i]]+ k*w[i]}。

dp = [0]*N
for i in range(1, n+1):           #枚舉物品for j in range (C,c[i]-1,-1): #枚舉背包容量for k in range(1,m[i]+1):     #用k遍歷第i組的所有物品if(j >= k*c[i]):          #第k個(gè)物品能裝進(jìn)容量j的背包dp[j] = max(dp[j], dp[j-k*c[i]]+k*w[i])
print(dp[C])

?多重背包解題思路3:二進(jìn)制拆分優(yōu)化

  • 一種簡單而有效的技巧。
  • 例如第i種物品有m_i= 25個(gè),這25個(gè)物品放進(jìn)背包的組合,有0~25的26種情況。
  • 不過要組合成26種情況,其實(shí)并不需要25個(gè)物品。
  • 根據(jù)二進(jìn)制的計(jì)算原理,一個(gè)十進(jìn)制整數(shù)X,可以用1、2、4、8、...這些2的倍數(shù)相加得到,例如25=16+8+1,這些2的倍數(shù)只有logX個(gè)
  • 題目中第i種物品有m_i個(gè),用logm_i個(gè)數(shù)就能組合出0 ~m_i種情況??倧?fù)雜度從O(C*\sum_{i=1}^{n})優(yōu)化到O(C*\sum_{i=1}^{n}log_2m_i)。

拆分要點(diǎn):

  • 注意拆分的具體實(shí)現(xiàn),不能全部拆成2的倍數(shù),而是先按2的倍數(shù)從小到大拆,最后是一個(gè)小于等于最大倍數(shù)的余數(shù)。
  • 保證拆出的數(shù)相加在[1, mi]范圍內(nèi),不會(huì)大于mi。
  • 例如mi= 25,把它拆成1、2、4、8、10,最后是余數(shù)10,10<16,這5個(gè)數(shù)能組合成1~25內(nèi)的所有數(shù)字,不會(huì)超過25。
  • 錯(cuò)誤示例:如果把25拆成1、2、4、8、16,相加的范圍就是[1,31]了。

多重背包解題思路4:單調(diào)隊(duì)列

因?yàn)檫@一講主要是講dp算法,所以就不在直接過多介紹其他算法,但這個(gè)方法優(yōu)化程度更高,有興趣的朋友可以看看這篇文章:單調(diào)隊(duì)列優(yōu)化多重背包(全網(wǎng)最詳細(xì)解析)?

模板題

【輸入描述】第一行是整數(shù)n和C,分別表示物品種數(shù)和背包的最大容量。接下來 n行,每行三個(gè)整數(shù) wi、ci、mi,分別表示第i個(gè)物品的價(jià)值、體積、數(shù)量。
【輸出描述】輸出一個(gè)整數(shù),表示背包不超載的情況下裝入物品的最大價(jià)值。
【輸入樣例】

4 20

3 9 3

5 9 1

9 4 2

8 1 3

【輸出樣例】

47

【代碼】

?代碼用二進(jìn)制拆分優(yōu)化來解答。

N = 100010
w = [0] * N;c = [0] * N;m = [0] * N
xw = [0] * N;xc = [0] * N   # 經(jīng)過二進(jìn)制拆分后的新體積和新價(jià)值,轉(zhuǎn)換后每個(gè)物體只有一個(gè),所以沒有新的數(shù)量n, C = map(int, input().split())
for i in range(1, n + 1):w[i], c[i], m[i] = map(int, input().split())# 以下是二進(jìn)制拆分
xn = 0  # 二進(jìn)制拆分后的新物品總數(shù)量
for i in range(1, n + 1):j = 1while j <= m[i]:  # 例:直到最后一個(gè)數(shù)m[i](余數(shù))出現(xiàn)m[i] -= j     # 減去已拆分的xn += 1xc[xn] = j * c[i]  # 新物品的體積xw[xn] = j * w[i]j <<= 1       # 二進(jìn)制枚舉:1,2,4...if m[i] > 0:      # 最后一個(gè)是余數(shù)xn += 1xc[xn] = m[i] * c[i]xw[xn] = m[i] * w[i]
# 以下是滾動(dòng)數(shù)組版本的0/1背包
dp = [0] * N
for i in range(1, xn + 1):  # 枚舉物品for j in range(C, xc[i] - 1, -1):  # 枚舉背包容量  xc[i] - 1這里的-1是因?yàn)閞ange函數(shù)是左閉右開區(qū)間,-1才能取到xc[i]dp[j] = max(dp[j], dp[j - xc[i]] + xw[i])
print(dp[C])

http://www.risenshineclean.com/news/6101.html

相關(guān)文章:

  • 遵義網(wǎng)站建設(shè)中心seo優(yōu)化專員編輯
  • 龍華建設(shè)網(wǎng)站企業(yè)郵箱查詢
  • 如何在路由器上做網(wǎng)站轉(zhuǎn)跳app下載推廣
  • 網(wǎng)站建設(shè)游戲公司免費(fèi)手游推廣代理平臺(tái)渠道
  • 深圳做公司網(wǎng)站seo管理
  • dw怎么做網(wǎng)站地圖奶茶店推廣軟文500字
  • 南山網(wǎng)站多少錢什么叫seo
  • 福州營銷型網(wǎng)站建設(shè)公司今日新聞聯(lián)播
  • 公司網(wǎng)站制作企業(yè)建站平臺(tái)哪個(gè)比較權(quán)威
  • 中交建設(shè)集團(tuán) 網(wǎng)站營銷型網(wǎng)站有哪些功能
  • 做3dmax的網(wǎng)站國內(nèi)搜索引擎排名第一
  • 網(wǎng)站服務(wù)器有哪些類型有哪些類型有哪些類型有哪些類型百度推廣一年大概需要多少錢
  • 蘭州做網(wǎng)站哪家專業(yè)株洲專業(yè)seo優(yōu)化
  • 做網(wǎng)站大圖片東莞關(guān)鍵詞排名推廣
  • html編輯器哪個(gè)軟件好用網(wǎng)站優(yōu)化的方法
  • 蘇州做公司郵箱企業(yè)網(wǎng)站營銷網(wǎng)站做的好的公司
  • 慶祝網(wǎng)站上線banner圖片外貿(mào)推廣公司
  • 我想做個(gè)網(wǎng)站百度收錄的網(wǎng)站
  • 游戲網(wǎng)站seo怎么做深圳哪里有網(wǎng)絡(luò)推廣渠避
  • 邢臺(tái)網(wǎng)站建設(shè)免費(fèi)做網(wǎng)站排名吸引人的微信軟文
  • 網(wǎng)站開發(fā)用什么開發(fā)工具好呢東莞整站優(yōu)化推廣公司找火速
  • 用dw做php網(wǎng)站北京seo服務(wù)銷售
  • 贛州大余做網(wǎng)站建設(shè)官方進(jìn)一步優(yōu)化
  • 哪有做網(wǎng)站的seo排名快速
  • 做網(wǎng)站怎么掙錢成人培訓(xùn)班有哪些課程
  • 臺(tái)州北京網(wǎng)站建設(shè)seo公司是做什么的
  • 深圳高端網(wǎng)站建設(shè)公司seo網(wǎng)絡(luò)推廣教程
  • 品牌策劃網(wǎng)站推薦搜索引擎 磁力吧
  • 尋找設(shè)計(jì)師的網(wǎng)站長春網(wǎng)站優(yōu)化流程
  • 網(wǎng)站建設(shè)基本教程免費(fèi)寫文案神器