動態規劃:
問題描述:
設u = (一共有amount數量的物品)是一組準備放入揹包中的物品.設揹包的容量為size.
定義每個物品都具有兩個屬性weight和value.
我們要解決的問題就是計算在所選取的物品總重量不超過揹包容量size的前提下使所選的物品總價值最大.
程式的設計:
設v[i, j]用來表示從前i項中取出來的裝入體積為j的揹包的最大價值.i的範圍是從0到amount,j是從0到size.這樣的話要 計算的值就是v[amount, size].v[0, j]對於所有的j的值都是0,因為這時候的包中沒有物品.同時v[i, 0]的值也是0,因為沒有物品可以放到size為0的揹包裡面.
所以有:
v[i, j] = 0 若i = 0 或 j = 0;
v[i, j] = v[i - 1, j] 若j < ui.weight;(當物品的重量大於揹包承重時,就不把物品放在裡面)
v[i, j] = max 若i > 0並且j >= ui.weight;
現在就可用動態規劃的方法運用上面的公式來填表求解了.
#include
#define w 1000
#define n 1000
typedef struct data
...goods;
int returnmax(int a, int b)
...int knapsack(goods *p, int a, int s)
...mv = v[a][s];
return mv;
}int main()
...還有一種純粹用陣列解決的方案,避免了結構體的效率底下,思路是一樣的
**如下:
#include
#define goodnum 5
using namespace std;
int main()
...,...,...,...,...};//good[i][0]:size||good[i][1]:value
int i,j,size,weight;
int v[goodnum+1][1000];
coutfor(i=0;i<=goodnum;i++)
v[i][0]=0;
for(i=0;i<=size;i++)
v[0][i]=0;
for(i=1;i<=goodnum;i++)
for(j=1;j<=size;j++)...
cout《揹包問題 動態規劃
(2009-10-18 15:14:31)
標籤:動態規劃
if 節點
揹包 for
雜談
分類:專業學習
01揹包問題描述:乙個旅行者有乙個最多能用m公斤的揹包,現在有n件物品,
它們的重量分別是w1,w2,...,wn,
它們的價值分別為p1,p2,...,pn.
若每種物品只有一件求旅行者能獲得最大總價值。
方式一:遍歷m*n的陣列,對應下圖包的總容量m=20,物品種類數n=5
**如下:
const int nres=5;//5種物品
int nresweight[nres+1]=;//每種物品對應重量
int nresvalue[nres+1]=;//每種物品對應價值
const int ntotlew=20;//揹包容量為20
int nvaluetable[nres+1][ntotlew+1]=;//動態價值表
int kitbag()
for(int i=1;i<=nres;i++)
for(int j=1;j<=ntotlew;j++)
if(nresweight[i]<=j) //容量大於等於當前物品重,j為當前包容量
if(nresvalue[i]+nvaluetable[i-1][j-nresweight[i]]>nvaluetable[i-1][j])
//如當前物品價值+包剩餘容量所能裝入最大價值》不裝當前物時包所能裝的最大價值,當前物品裝入包.
nvaluetable[i][j]=nresvalue[i]+nvaluetable[i-1][j-nresweight[i]];
else//當前物品不裝入包,當前包容量下的最大價值仍然是原來的價值
nvaluetable[i][j]=nvaluetable[i-1][j];
else//包容量不足以裝入當前物品時,沿用原來的包容量最大價值
**如下:
int recursionbag(int nr,int nw)//傳入資源數,包容量
if(nr==0||nw==0){
return 0;
if(nvaluetable[nr][nw]!=0){
//當前節點是已訪問過的節點,直接返回儲存的最優值
return nvaluetable[nr][nw];
if(nw>=nresweight[nr])//包容量大於等於當前物品重
{//獲得物品放入和不放入兩種情況中的價值最大者
nvaluetable[nr][nw]=max(nresvalue[nr]+recursionbag(nr-1,nw-nresweight[nr]),//物品入包後的價值
recursionbag(nr-1,nw));//物品不入包的最大價值
else//包容量不足以放入當前物品
nvaluetable[nr][nw]=recursionbag(nr-1,nw);
return nvaluetable[nr][nw];
對比兩種方式可知,第二種方式遍歷的資料量為黃色標註結點,要小於第一種方式的資料訪問量。
不過當節點深度上千後,如果包容量遠小2^n,比如為 10000,這時前一種方法要快得多。估計這時,遞迴對訪問過的節點雖然不再訪問它的子節點,但是這樣重複訪問到的父節點數量過於龐大。
揹包問題 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...