問題描述:
給定n個物品和乙個揹包。物品
i的重量為
wi,價值為
vi,揹包容量為c。
如何選擇裝入揹包中的物品,使得裝入揹包的物品的價值最大?
從第n個物品開始依次向前裝,裝的順序為:(
n, n-1, n-2,
…, i+1, i, i-1,
…, 1
)函式、陣列等宣告:
n 共有
n個物品
c 揹包總重量為
cv[i] 物品
i價值為
viw[i]物品
i的重量為
wix[i] x[i]=0,第
i件物品不裝入揹包,
x[i]=1,第i
件物品裝入揹包
m(i, j)
:揹包容量為
j,選擇物品為
n, n-1, n-2,
…, i+1, i
裝入揹包產生的價值
knapsack(int v,int w,int c,int n,int m[10]) 確定m(i, j)的值,得到最優解
traceback(int m[10],int w,int c,int n,int x)構造最優解
(x1,x2,
…,xn)
演算法問題分析:
用二維陣列
m[i][j], 0≤j≤
c, 來儲存
m(i, j)
的值。求解
0-1揹包問題就是在二維陣列
m中填入相應的值。
m[1][c]中的值就是該揹包問題的解
尋找遞推關係的過程:
第一,包的容量比商品
i體積小,裝不下,此時的價值與前
n-i個的價值是一樣的,即
m(i,j)=m(i+1,j)
;第二,還有足夠的容量可以裝該商品,但裝了也不一定達到當前最優價值,所以在裝與不裝之間選擇最優的乙個,即
m(i,j)=max{
m(i+1, j)
,m(i+1,j-wi)+vi }其中
m(i+1,j)表示不裝
i的價值,
m(i+1,j-wi)+vi
表示裝了第
i個商品,揹包容量減少
w(i),
但價值增加了
v(i)
;遞推關係式如下:
二維陣列
m中最先填入物品
n的最優解
然後依次按照遞推式求出
m(i,j).
knapsack演算法過程:
void knapsack(int v,int w,int c,int n,int m[10])
for(int j=w[n];j<=c;j++)
//從第n-1個到第2個
for(int i=n-1;i>1;i--)
for(int j=w[i];j<=c;j++)
}//第1個
if(c>=w[1])
}
構造最優解(x1,x2,…
,xn)
演算法:如果
m[1][c]=m[2][c], 則
x1=0,
否則x1=1;
如果x1=0, 則由
m[2][c]
構造解;
如果x1=1, 則由
m[2][c-w1]
構造解;
依次類推,可構造出相應的最優解
:(x1,x2,
…,xn
)traceback演算法過程:
void traceback(int m[10],int w,int c,int n,int x)//構造最優解(x1,x2,…,xn)演算法
for(int j=w[n];j<=c;j++)
//從第n-1個到第2個
for(int i=n-1;i>1;i--)
for(int j=w[i];j<=c;j++)
}//第1個
if(c>=w[1])
}//x[i]=0,第i件物品不裝入揹包,x[i]=1,第i件物品裝入揹包
void traceback(int m[10],int w,int c,int n,int x)//構造最優解(x1,x2,…,xn)演算法
for(int i=1;i<=n;i++)//初始化
動態規劃 01揹包
最優二叉查詢樹.cpp 定義控制台應用程式的入口點。01揹包問題。include stdafx.h include include define n 3 the number of real node define m 10 using namespace std int tmain int arg...
01揹包動態規劃
0 1揹包 問題描述 乙個旅行者有乙個最多能用 m公斤的揹包,現在有 n件物品,它們的重量 分別是w1,w2 wn,它們的價值分別為 c1,c2,cn.若每種物品只有一 件求旅行者能獲得最大總價值。輸入格式 w 第一行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 w第2.n 1 行...
0 1揹包(動態規劃)
題意 有n件物品和乙個容量為v的揹包。第i件物品的體積是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。基本思路 這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不放。用子問題定義狀態 即f i v 表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程...