由m(i,j)的遞迴式容易證明,在一般情況下,對每乙個確定的i(1≤i≤n),函式m(i,j)是關於變數j的階梯狀單調不減函式。跳躍點是這一類函式的描述特徵。在一般情況下,函式m(i,j)由其全部跳躍點唯一確定。如圖所示。
對每乙個確定的i(1≤i≤n),用乙個表p[i]儲存函式m(i,j)的全部跳躍點。表p[i]可依計算m(i,j)的遞迴式遞迴地由表p[i+1]計算,初始時p[n+1]=。
乙個例子:n=3,c=6,w=,v=。
舉個栗子:
n=5,c=10,w=,v=。跳躍點的計算過程如下:
初始時p[6]=
因此,q[6]=p[6]⊕(w[5],v[5])=
p[5]=
q[5]=p[5]⊕(w[4],v[4])=
p[4]= p[5]與q[5]的並集p[5]∪q[5]=中跳躍點(5,4)受控於跳躍點(4,6)。將受控跳躍點(5,4)清除後,得到p[4]
q[4]=p[4]⊕(6,5)=
p[3]=
q[3]=p[3]⊕(2,3)=
p[2]=
q[2]=p[2]⊕(2,6)=
p[1]=
p[1]的最後的那個跳躍點(8,15)即為所求的最優值,m(1,c)=15
演算法思想:
先在 p(i-1)的元素 j 上得到乙個新狀態,然後 w 小於它的不受影響,直接搬,w 等於它的,對 v 取大更,w 大於它的,根據 v 值直接pass 掉 不合法的點(w 大但 v 小於前邊的),同時,出現了新狀態往裡寫的時候,也要注意,w 大 v 也大時才合法,才可以往裡寫,反之直接扔掉。(在跳躍點函式影象中,保留的的是 max ,即p(i-1),q(i-1)倆函式圖取 max 的合圖)
記錄好錶之後,從終態開始往回倒找解路徑即可。
#include
using
namespace std;
const
int n =5;
template
<
class
type
>
intknapsack
(int n,type c,type v[
],type w,
int*
*p,int x)
;template
<
class
type
>
void
traceback
(int n,type w[
],type v[
],type *
*p,int
*head,
int x)
;int
main()
,w=;
//下標從1開始
int x[n+1]
;int
**p =
newint*[
50];for
(int i=
0; i<
50; i++
) cout<<
"待裝物品重量分別為:"
<
for(
int i=
1; i<=n; i++
) cout<
cout<<
"待裝物品價值分別為:"
<
for(
int i=
1; i<=n; i++
) cout<
cout<<
"揹包能裝的最大價值為:"
<<
knapsack
(n,c,v,w,p,x)
<
cout<<
"揹包裝下的物品編號為:"
<
for(
int i=
1; i<=n; i++)}
cout<
for(
int i=
0; i<
50; i++
)delete
p;return0;
}template
<
class
type
>
intknapsack
(int n,type c,type v[
],type w,
int*
*p,int x)
//如果 p[k][0]==y而mif
(k<=right && p[k][0
]==y)
k++;}
// 若p[k][0]>=y且m> =p[k][1],判斷是不是當前i的最後乙個跳躍點的受控點
//若不是則為i的跳躍點儲存
if(m>p[next-1]
[1])
//若是,則對下乙個元素進行判斷。
while
(k<=right && p[k][1
]<=p[next-1]
[1])
}while
(k<=right)
left = right +1;
right = next -1;
// 第i-1個物品第乙個跳躍點的位置 head[n]指第n個物品第乙個跳躍點的位置
head[i-1]
= next;
} cout<<
"head:"
<
for(
int i=
0;i<=n+
1;i++
) cout<<
"p[6-1]:"
<
for(
int i=
0;i1;i++
)traceback
(n,w,v,p,head,x)
;return p[next-1]
[1];
}//x陣列儲存對應物品0-1向量,0不裝入揹包,1表示裝入揹包
template
<
class
type
>
void
traceback
(int n,type w[
],type v[
],type *
*p,int
*head,
int x)}}}
執行效果:
動態規劃01揹包問題之跳躍點解法
m i j ma xm i,j max m i,j max m i j 代 表餘量j 從第乙個 物品到第 i個物品 的最優價 值m i,j 代表餘量j從第乙個物品到第i個物品的最優價值 m i,j 代表餘量 j從第一 個物品到 第i個物 品的最優 價值p i 代表m i,j 的跳躍 點點 集p i ...
01揹包問題 C 解法
01揹包問題 假設現有容量m的揹包,有i個物品,重量分別為w 1 w 2 w i 價值分別為p 1 p 2 p i 將哪些物品放入揹包可以使得揹包的總價值最大?最大價值是多少?示例1 m 10,i 3,物品重量 價值 3 4 4 5 5 6 第一種 不帶備忘的自頂向下法 using system n...
0 1揹包的遞迴解法
1 輸入物品個數n,揹包容量w 2 定義物品價值列表v,物品體積列表w 3 def rec i,j 從第i個物品開始挑選總重小於j的部分 4 res 0 5 if i n 剩餘物品為0 6 return res 7 elif j w i 無法挑選該物品 8 res rec i 1,j 9 else ...