0/1揹包問題動態規劃 空間複雜度是o(C)
阿新 • • 發佈:2019-01-30
有num個物品,總揹包容量為Capacity, 求不超過揹包總容量的前提下使得揹包裡的物品的價值達到最大的物品是哪些物品。
對於每個物品,只有兩種選擇,要麼裝要麼不裝進揹包。
那麼在考慮前 i 個物品時,在當前容量為 j 的條件下,如果這個物品的體積小於當前揹包剩下體積,且裝入此物品的價值比不裝此物品的價值大,就裝入此物品 ,設第 i 個物品的體積為 vol[ i ] ,價值 為 val [ i] ,result [ j ]表示容量為 j 時的價值,那麼
result [ j ] = max{ result[ j ], result[ j - vol[ i ] ] + val[ i ]}, j>=vol[j]
如果 j < vol[ i ] ,說明當前的容量小於 當前物品的體積,肯放就是不放該物品了,那麼在這個容量下的值就是不變的
這樣對每個物品考慮完後,result [ Capacity ] 就是結果,
值得注意的是,求每個 result[ j ] 時,由於都只會訪問 result [ k ] ,k<j, 所以求result[ j ] 時 ,用逆序,本質也就是如果一個物品放了一次,就不能再放第二次了。
空間複雜度是 o(Capacity),
程式碼如下:
#include <iostream> #include <vector> using namespace std; int main(int argc, char** argv) { cout<<"0/1 揹包問題"<<endl<<endl<<"輸入揹包總容量"<<endl; size_t Capacity; cin>>Capacity; cout<<"輸入物品總數目"<<endl; size_t num; cin>>num; cout<<"輸入物品的體積和價值"<<endl; vector<int> vol; vector<int> val; int temp1,temp2; int i=0,j=0; for(i=0;i<num;++i) { cin>>temp1>>temp2; vol.push_back(temp1); val.push_back(temp2); } vector<int> result(Capacity+1,0); int temp; for(i=0;i<num;++i) { for(j=Capacity;j>=vol[i];--j) { temp = result [j-vol[i]] + val[i]; if(temp > result[j]) result[j] = temp; } } cout<<"最大價值為 "<<result[Capacity]<<endl; return 0; }
執行結果