1.動態規劃是用空間換取時間的一種方法的抽象,其關鍵是發現子問題和記錄其結果,然後利用結果減輕計算量。0/1揹包問題就應用了動態規劃的思想。
2.0/1揹包問題:乙個揹包最多可以裝m公斤的東西,現在有n件物品,分別為x1,x2...xn,它們的重量分別為m1,m2...mn,它們的價值分別為v1,v2...vn,若某種物品只有一件,它可以放進包中,也可以不放進包中,問如何選取物品可以使得包中的物品的價值最大。
思路:目標函式為 max∑xivi(i=1,2...n),約束條件為 ∑ximi<=m(i=1,2...n) ,其中xi=。可以將揹包問題的求解過程看做是一系列的決策過程,即決定哪些東西放入揹包,哪些不放入揹包,如果乙個問題的最優解包含物品n,即xn=1,那麼其餘x1,x2...xn-1構成子問題,求它們在中路 m-mn 中的最優解。
我們以最大容量m=10和物品個數n=3為例,三個物品重量分別為3,4,5,物品價值分別為4,5,6,c[i][j]儲存當允許重量為j時,從前i個物品中選擇可以得到的最大價值。第一行均為0,因為沒有物品可以選擇;第二行當j=0,1,2時c[i][j]=0,因為可以允許的重量小於任何物品的重量,當j=3時,可以將第乙個物品裝進去了,c[i][j] = 4,這一行剩下的部分均為4,因為只有乙個物品可以選擇;第三行,當j=3時,表示可以從1,2兩個物品中選擇,但是總重量不可以超過3,所以c[i][j] = 4,但是當j=4時,我們可以選擇有第2個物品(此時最大價值為c[i-1][j-4]+5=c[2][0]+5=5)或沒有第2個物品(此時最大價值為c[i-1][j]=c[2][4]=4),所以最後的結果為5,依次類推。
我們將在總重量不超過m的前提下,前i種物品的總**所能達到的最高值定義為a(i, m)。
a(i, m)的遞推關係為:
a(0, m) = 0
a(i, 0) = 0
如果wi > m, a(i, m) = a(i - 1, m)
如果wi ≤ m, a(i, m) = max
//假設m=100,n=10,也就是10個物品、總重量最大為100
for(i=0;i<10;i++)
for(j=0;j<100;j++)
c[i][j]=0;/*初始化陣列*/
for(i=1;ic[i-1][j])
/*如果本物品的價值加上揹包剩下的空間能放的物品的價值*/
/*大於上一次選擇的最佳方案則更新c[i][j]*/
c[i][j]=v[i]+c[i-1][j-v[i]];
else
c[i][j]=c[i-1][j];
}else c[i][j]=c[i-1][j];
}
3.揹包問題的應用
程式設計之美——陣列分割問題:有乙個沒有排序、元素個數為2n的正整數陣列,要求:如何能把這個陣列分割為元素個數為n的兩個陣列,並使兩個子陣列的和最接近。
isok[i][v]表示是否可以找到i個數,使得它們之和為v
初始化:isok[0][0]=true;
isok[i][v]=false; i>0,v>0
for(k = 1,k <= 2*n; k++)
}
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...
揹包問題 01揹包
有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...
揹包問題(01揹包)
1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...