重磅乾貨,第一時間送達正則表達式
揹包問題是一個經典的動態規劃模型。它既簡單形象容易理解,又在某種程度上可以揭示動態規劃的本質,故很多教材都把它做爲動態規劃部分的第一道例題.算法
徹底揹包問題數組
有n個重量和價值分別爲wi,vi的物品,從這些物品中挑選出總重量不超過W的物品,求全部挑選方案中價值總和的最大值
1≤n≤100
1≤wi,vi≤100
1≤W≤10000微信
輸入:
整數用空格隔開 數據結構
第一行有兩個整數N,V 表明物品種數和揹包容積機器學習
接下來有N行,每行兩個整數用空格隔開,表明物品體積和價值ide
輸出:
在揹包容量下可以最大化的價值函數
輸入樣例學習
4 6 1 1 2 3 3 4 4 5
輸出樣例:3d
9
與零一揹包不一樣的是,零一揹包中的物品是不能夠重複拿取的,只能夠拿取當前物品或者不拿取當前物品,不能夠拿取多個,徹底揹包的物品是能夠任意拿取多個的來構成不超過揹包容量而且構成的總價值是最大的
動態規劃的核心是找到dp公式或者狀態轉移的方程,理解清楚中間的過程是怎麼樣進行變化的,由於動態規劃老是要利用到以前歷史上的最佳方案,因此dp數組裏面存儲的確定是歷史上存儲的最佳方案,一開始的時候咱們是能夠藉助excel表格來幫助咱們理解dp數組是怎樣生成的
咱們能夠這樣想:當前個人揹包容量有多少,並且我能夠選擇的物品的範圍是什麼,那麼這兩個變量就能夠肯定一個值了,咱們能夠計算出當前揹包容量對於當前能夠選擇的物品範圍構成的最大價值
由輸入可知第一個物品爲1 1 即價值爲1,所佔的容量也爲1。
根據f[i][j]=max(f[i][j-w[i]]+v[i])可知,從第一個物品開始,因爲今天這個問題屬於徹底揹包問題,故兩層循環中,第一層循環爲遍歷物品,第二層循環爲從小到大擴大揹包容量不斷塞進更多的當前物品。
f[1][0]=max(f[1][0],f[1][0-1]+2) 不執行
執行 f[1][0]=f[0][0]
從上式能夠知道我咱們取不到f[1][0-1] 故加個判斷j>=w[i]便可,若知足就能夠加入物品,不知足就不更新仍維持0
f[1][1]=max(f[1][1],f[1][1-1]+2)
f[1][2]=max(f[1][2],f[1][2-1]+2)
f[1][3]=max(f[1][3],f[1][3-1]+2)
f[1][4]=max(f[1][4],f[1][4-1]+2)
f[1][5]=max(f[1][5],f[1][5-1]+2)
這樣第一個物品結束後,咱們來看看整個二維數組的更新狀況
f[1][5]就表示了在選擇第一個物品的時候,容量爲5的狀況下的最大價值爲5
接下來更新第二個物品
加個判斷j-w[i]>=0,若知足就能夠加入物品,不知足就不更新仍維持0
f[2][0]=max(f[2][0],f[2][0-2]+3) 不執行
故執行f[2][0]=f[1][0]
f[2][1]=max(f[2][1],f[2][1-2]+3) 不執行
故執行f[2][1]=f[1][1]
f[2][2]=max(f[2][2],f[2][2-2]+3)
f[2][3]=max(f[2][3],f[2][3-2]+3)
f[2][4]=max(f[2][4],f[2][4-2]+3)
f[2][5]=max(f[2][5],f[2][5-2]+3)
這樣第二個物品結束後,咱們來看看整個二維數組的更新狀況
以此類推最後獲得整個二維數組的狀況爲
1a=input() 2n, m=list(map(int, a.split())) 3w=[0 for i in range(n + 1)] 4v=[0 for i in range(n + 1)] 5f=[0 for i in range(m + 1)] 6for i in range(1, n + 1): 7 b=input() 8 w[i], v[i]=list(map(int, b.split())) 9 10for i in range(1, n + 1): 11 for j in range(1, m + 1): 12 if j >= w[i]: 13 f[j]=max(f[j], f[j - w[i]] + v[i]) 14 # 這個是考慮到能夠選取多個物品的狀況 15 16print(f[-1])
1int main(){ 2 int N,V; 3 cin>>N>>V; 4 vector<int> weight(N+1),value(N+1); 5 for(int i=1;i<=N;i++) 6 cin>>weight[i]>>value[i]; 7 vector<vector<int>> dp(N+1,vector<int>(V+1,0)); 8 for(int i=1;i<weight.size();i++){ 9 for(int j=0;j<=V;j++){ 10 11 dp[i][j]=dp[i-1][j]; 12 13 if(j-weight[i]>=0) 14 dp[i][j]=max(dp[i-1][j],dp[i][j-weight[i]]+value[i]); 15 } 16 } 17 cout<<dp[N][V]<<endl; 18} 19
2020大廠筆試 | 網易提早批(1)
2020大廠筆試 | 網易提早批(2)
使人頭疼的揹包九講(1)0/1揹包
劍指offer刷題交流羣
掃碼添加微信,必定要備註研究方向+地點+學校+暱稱(如機器學習+上海+上交+湯姆),只有備註正確才能夠加羣噢。
▲長按加羣