你們都知道01揹包了吧?html
若是不知道,能夠去這裏:https://www.cnblogs.com/kingderman/p/11224847.htmlc++
徹底揹包問題就是01揹包的升級版(如題)學習
就是仍是你要往揹包裏面塞東西,可是你旁邊有一個坑B在施展複製魔法,讓你的物品變得無限多,就是說你能夠把同一個物品塞不少次!spa
這是傳統的二維線性DP的作法。dp[i][j]表示從前i個物品中選擇體積爲j的物品放入揹包中。物品價值的最大值。code
這個代碼我就不貼了,要本身去思考纔可能進步!(我是不會告訴你是我偷懶的)htm
固然,這是一個二維的作法,空間複雜度並不低。因此,咱們學習01揹包,將二維變成一維吧!blog
#include<bits/stdc++.h> using namespace std; int n,v; int val[10010],wei[10010]; int dp[10010]; int main() { cin>>n>>v;//n是物品的個數;v是揹包容積 for(int i=1;i<=n;i++) { cin>>wei[i]>>val[i];//wei是第i個物品的體積;val是第i個物品的價值 } for(int i=1;i<=n;i++) { for(int j=wei[i];j<=v;j++)//注意,這裏是從wei[i]開始,循環到v { dp[j]=max(dp[j],dp[j-wei[i]]+val[i]);//跟01揹包同樣的狀態轉移方程 } } cout<<dp[v]<<endl;//輸出最後一個數便可 return 0; }
咱們會發現,這個和01揹包的代碼很是像!ci
沒錯!由於標題☝it
仔細對比之下,發現惟一的區別就是嵌套的第二個循環,就是int j的那個,io
01揹包是:for(int j=v;j>=wei[i];j--)
而徹底揹包是:for(int j=wei[i];j<=v;j++)
不難發現,一個是逆推,一個是正推
你們記住了嗎?
這個內容我如今尚未徹底吃透,因此本蒟蒻沒法解釋爲何一個是正推一個是逆推,只要記住就好啦!畢竟是模板嘛QWQ!