#
include
#include
using
namespace std;
const
int n =
10010
;int f[n]
, v[n]
, w[n]
;// f[i][j]: 前i種物品中,空間為j時的最大價值。
intmain()
#
include
#include
using
namespace std;
const
int n =
10010
;int f[n]
, v[n]
, w[n]
;// f[i][j]: 前i種物品中,空間為j時的最大價值。
intmain()
注意: 01揹包與完全揹包的**僅在第二維的遍歷順序有差異,這是因為兩者狀態轉移方程的不同:
01揹包:f[i]
[j]= max(f[i-1]
[j], f[i-1]
[j-v[i]
] + w[i]);
完全揹包:f[i]
[j]= max(f[i-1]
[j], f[i]
[j-v[i]
]] + w[i]
);
可以發現01揹包由第i-1行轉移而來,完全揹包由第i行轉移而來。
二進位制優化:對於可選n次的揹包,可將其合併成若干個揹包(合併得到揹包的組合必須能夠表示1-n中的任意乙個數), 這樣可用01揹包求解。
#
include
#include
using
namespace std;
const
int n =
23000
;int f[n]
, v[n]
, w[n]
;int
main()
if(s) v[cnt]
= s*x, w[cnt++
]= s*y;
}for
(int i =
1; i < cnt; i++
)for
(int j = m; j >= v[i]
; j--
) f[j]
=max
(f[j]
, f[j-v[i]
]+ w[i]);
cout << f[m]
;return0;
}
滑動視窗優化:通過滑動視窗求最大值,時間複雜度o(n*v), 其中n為物品數,v為給定的空間。
f(i,j)=max(f(i−1,j),f(i−1,j−v)+w,⋯,f(i−1,j−sv)+sw)
f(i,j−v)=max(f(i−1,j−v),f(i−1,j−2v)+w,⋯,f(i−1,j−(s+1)v)+sw)
#
include
#include
#include
using
namespace std;
const
int n =
1010
, m =
20010
;int v[n]
, w[n]
, s[n]
;int dp[m]
, g[m]
, qq[m]
;int
main()
for(
int i =
1; i <= n; i++
)while
(hh <= tt && g[qq[tt]]+
(k - qq[tt]
)/ v[i]
* w[i]
<= g[k]
) qq[
++tt]
= k;
if(hh <= tt) dp[k]
= g[qq[hh]]+
(k - qq[hh]
)/ v[i]
* w[i];}
}}cout << dp[m]
<< endl;
return0;
}
#
include
using
namespace std;
const
int n =
110;
int f[n]
, v[n]
[n], w[n]
[n], cnt[n]
;// f[i][j]: 前i組物品中,空間為j時的最大價值。
// v[i][j]: 第i組物品的第j個; cnt[i]: 第i組的物品個數。
intmain()
for(
int i =
1; i <= n; i++
)
cout << f[m]
;return0;
}
#
include
using
namespace std;
const
int n =
1010
;int dp[n]
;// dp[i][j]: 前i類物品體積為j的最大價值
intmain()
else
for(
int k =
1; k <= s; k *=2)
s -= k;}if
(s)}
} cout << dp[m]
<< endl;
return0;
}
#
include
#include
#include
using
namespace std;
const
int n =
110;
int n, m;
int v[n]
, w[n]
;int h[n]
, e[n]
, ne[n]
, idx;
int dp[n]
[n];
// dp[i][j]: 對於i為根節點的子樹,體積為j時的最大價值
void
add(
int a,
int b)
void
dfs(
int u)}}
// 加上根節點的值
for(
int j = v[u]
; j <= m; j++
) dp[u]
[j]+= w[u];}
intmain()
else
}dfs
(root)
; cout << dp[root]
[m]<< endl;
return0;
}
揹包問題模板
特點 每種物品只有一件 子問題定義狀態 bag i v 前i件物品放到乙個容量為v的揹包中可以獲得最大價值 轉移狀態方程 bag i v max bag i 1 v bag i 1 v weight i value i 模板 include include using namespace std i...
揹包問題模板
01揹包在時間複雜度上都是n n v 在這個基礎之上已經不能再進行優化了,在空間複雜度上,我們首先看一下複雜度為o n v 的程式 for int i 1 i n i for int j 0 j w j 但是我們還可以將空間複雜度壓縮為o v 我們會發現這裡每次更新第i層都只是看第i 1層,其他層的...
模板 揹包問題
include include define max a,b a b a b using namespace std const int n 1005 int n,v,v n w n int dp n voidf intmain f printf d n dp v return0 include i...