gpt4 book ai didi

algorithm - 0/1 背包动态规划优化,从2D矩阵到1D矩阵

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:44:12 25 4
gpt4 key购买 nike

我需要维基百科的一些说明:Knapsack , 一边

This solution will therefore run in O(nW) time and O(nW) space. Additionally, if we use only a 1-dimensional array m[W] to store the current optimal values and pass over this array i+1 times, rewriting from m[W] to m[1] every time, we get the same result for only O(W) space.

我无法理解如何将二维矩阵转换为一维矩阵以节省空间。此外,rewriting from m[W] to m[1] every time 意味着什么(或者它是如何工作的)。

请提供一些例子。假设我有集合 {V,W} --> {(5,4),(6,5),(3,2)} 且 K = 9。

一维数组会是什么样子?

最佳答案

我知道这是一个老问题。但是我不得不花一些时间来搜索这个,我只是在这里记录这些方法以供任何人将来引用。

方法一
使用 N 行的直接 2D 方法是:

int dp[MAXN][MAXW];
int solve()
{
memset(dp[0], 0, sizeof(dp[0]));
for(int i = 1; i <= N; i++) {
for(int j = 0; j <= W; j++) {
dp[i][j] = (w[i] > j) ? dp[i-1][j] : max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);
}
}
return dp[N][W];
}

这使用 O(NW) 空间。

方法二
您可能会注意到,在为特定行计算矩阵的条目时,我们只查看前一行而不是之前的行。这可以被利用来仅维护 2 行并继续交换它们作为当前行和上一行的角色。

int dp[2][MAXW];
int solve()
{
memset(dp[0], 0, sizeof(dp[0]));
for(int i = 1; i <= N; i++) {
int *cur = dp[i&1], *prev = dp[!(i&1)];
for(int j = 0; j <= W; j++) {
cur[j] = (w[i] > j) ? prev[j] : max(prev[j], prev[j-w[i]] + v[i]);
}
}
return dp[N&1][W];
}

这需要 O(2W) = O(W) 空间。 cur 是第 i 行,prev 是第 (i-1) 行。
方法三
如果你再看一遍,你会发现当我们在一行中写一个条目时,我们只查看前一行左边的项目。我们可以使用它来使用单行并从右到左处理它,这样当我们计算一个条目的新值时,其左侧的条目具有它们的旧值。这是一维表法。

int dp[MAXW];
int solve()
{
memset(dp, 0, sizeof(dp));
for(int i =1; i <= N; i++) {
for(int j = W; j >= 0; j--) {
dp[j] = (w[i] > j) ? dp[j]: max(dp[j], dp[j-w[i]] + v[i]);
}
}
return dp[W];
}

这也使用了 O(W) 空间,但只使用了一行。必须反转内循环的主要原因是因为当我们使用dp[j-w[i]]时,我们需要外循环上一次迭代的值。为此,必须以从大到小的方式处理 j 值。

测试用例(来自http://www.spoj.com/problems/PARTY/)

N = 10, W = 50
w[] = {0, 12, 15, 16, 16, 10, 21, 18, 12, 17, 18} // 1 based indexing
v[] = {0, 3, 8, 9, 6, 2, 9, 4, 4, 8, 9}

答案 = 26

关于algorithm - 0/1 背包动态规划优化,从2D矩阵到1D矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17246670/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com