01背包
题目描述
有 n n n 个重量和价值分别为 w i w_i wi, v i v_i vi 的物品。从这些物品中挑选出总重量不超过 W W W 的物品,求所有挑选方案中价值总和的最大值。
数据范围:
1 ≤ n ≤ 100 1\le n\le100 1≤n≤100
1 ≤ w i , v i ≤ 100 1\le w_i,v_i\le100 1≤wi,vi≤100
1 ≤ W ≤ 10000 1\le W\le10000 1≤W≤10000
优化前
- 递推式:
d p [ 0 ] [ j ] = 0 d p [ i + 1 ] [ j ] = { d p [ i ] [ j ] , j < w i m a x { d p [ i ] [ j ] , d p [ i ] [ j − w i ] + v i } , j ≥ w i \begin{split} dp[0][j]&=0 \\ dp[i + 1][j]&=\begin{cases} dp[i][j]&,j<w_i \\ max\{dp[i][j],dp[i][j-w_i]+v_i\}&,j\ge w_i \end{cases} \end{split} dp[0][j]dp[i+1][j]=0={ dp[i][j]max{ dp[i][j],dp[i][j−wi]+vi},j<wi,j≥wi
- 代码:
// 输入
int n, W; // n -- 物品个数;W -- 最大重量
int w[WMAX], v[VMAX]; // w[WMAX] -- 物品重量;v[VMAX] -- 物品价值
int dp[MAX][MAX] // dp数组,与记忆化数组一样,必须足够大
void solve(void)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= W; j++)
{
if (j < w[i])
dp[i + 1][j] = dp[i][j];
else
dp[i + 1][j] = max(dp[i][j], dp[i][j - w[i]] + v[i]);
}
}
printf("%d\n", dp[n][W]);
}
优化一:二维数组
由 d p [ i + 1 ] [ j ] = m a x { d p [ i ] [ j ] , d p [ i ] [ j − w i ] + v i } dp[i + 1][j]=max\{dp[i][j],dp[i][j-w_i]+v_i\} dp[i+1][j]

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



