0/1揹包問題
物品集合u={u1,u2…un},體積分別為s1,s2…..sn,價值分別為v1,v2….vn;容量c的揹包。設計演算法實現放入揹包的物品價值最大。
輸入描述
第一行輸入物品數n和揹包的容量c,接下來n行分別輸入每個物品體積及價值
輸出描述
輸出最大價值數
輸入樣例
3 10
3 4
4 5
5 6輸出樣例
11每個物品有裝入和不裝入兩個選擇,定義n維向量x=(x1,x2,x3,~~xn),其中xk=1表示物品k裝入,xk=0表示不裝入,因此乙個0-1向量代表了一種裝載方案,
現在要求給出一種最優裝載方案x,滿足總容量<=c,使得總價值最大,那麼考慮前i個物品1,2,3~~i,以及揹包容量j,
記d[i][j]為前i個物品在揹包容量為j的情況下所能得到的最大價值。
它滿足以下遞推關係:
(1) d[0][j]=0,j=0,1,2,,c; 物品為0時肯定最大價值全為0 這是遞推起點 需要初始化
(2) 若j
d[i][j]的計算要用到上一行的兩個元素,因此計算順序和填二維陣列的順序是一樣的,從左往右,再從左往右
則最後右下角的d[n][c]就是最大價值
#includeusingnamespace
std;
#define max 1000
#define n 20
#define max(a,b) a>b?a:b
intd[max][max];
int fill(int n,int c,int w,int
v) //
d[i-1][j]是不放入時的價值 d[i-1][j-w[i]]+v[i]是放 入時,前i-1個物品的價值加上當前物品的價值
}
return
d[n][c];
}int
main()
那麼根據這個樣例列出的表如下:以物品個數i為縱座標,揹包容量j為橫座標,表中資料即為前i個物品在揹包容量為j時的情況下所能得到的最大價值。
i⁄j012
3456
78910
111200
0000
0000
0000
1000
4444
4444
4420
0045
5599
9999
3000
4566
9101111
1115
這裡揹包最大容量是10,其實只要列到10就好了,但是為了方便理解,這裡列到12是把所有物品的容量都加起來了。其實這個表是把所有可能的情況列出來了,
單獨乙個或者兩個,或者三個物品放入。
最優裝載方案即x=(x1,x2,x3,~~xn),可以從d中得到,從右下角的d[n][c]開始往前回溯,根據遞推關係(2),如果d[i][j]==d[i-1][j],說明xi=0,否則xi=1。
int optload(int n,int c,int w,int v,intx)
else
}return
d[n][c];
}
上述是用的二維陣列
接下來用一維陣列來解決這個問題,注意一下內層迴圈要逆序
#includeusingnamespace
std;
#define max 1000
#define n 20
#define max(a,b) a>b?a:b
int d[max];//
這裡系統已經把陣列全初始化為0了,相當於遞推起點
int fill(int n,int c,int w,int
v)
//for(int j=c;j>=0;j--) 這個for迴圈和上面那個是等價的
////
如果值得改變並且j的空間還裝得下就賦新值
}
return
d[c];
}int
main()
//然而用一維陣列不足的是,雖然優化了動態規劃的空間,但是該方法不能找到最優解的解組成,
//因為動態規劃尋找解組成一定得在確定了最優解的前提下再往回找解的構成,而優化後的動態規劃只用了一維陣列,
//每一次迴圈之前的資料會被覆蓋掉,所以沒辦法尋找,所以兩種方法各有其優點。
用一維和二維陣列解決超大揹包問題
現在有乙個容量為c的揹包和n個重量和價值已知的物品.現在要從這n個物品中挑選出一些物品,使得選擇的物品的總重量不超過揹包的容量,且總價值最大.此題的資料範圍 1 c 10 8 10的8次方 1 n 100 輸入描述 有多組測試資料.第一行乙個正整數t t 15 表示測試資料組數.對於每組測試資料 第...
01揹包 分組揹包(一維 二維 搜尋
上面的 中寫了01揹包 分組揹包的一維,二維陣列方法,還有搜尋法以及自己的一些思考。個人對於網上分組揹包的二維轉移方程覺得還不太完善 或者我自己理解的不太對 而且沒有找到很完全的 可能恰好沒找到 所以就自己寫了,有附題目位址,如果想看二維陣列分組揹包,直接拉到最後,前面都是廢話。不想看原位址的,下面...
一維和二維字首和
出自南昌理工學院acm集訓隊 二維字首和 字首和是什麼呢?字首就是乙個陣列的某項下標之前 包括此項元素 的所有陣列元素的和。簡單點來說就是有n個數,求n個數包括第n個數的所有數的和。s n a 1 a 2 a 3 a 4 a n 字首和最基本的用法就是解決求某個區間所有數的和,經過字首和的預處理,可...