给定n个物品的重量和价值,将这些物品放入容量为W的背包中,得到背包中的最大总价值。换句话说,给定两个整数数组 val[0..n-1] 和 wt[0..n-1],它们分别表示与 n 个项目相关的值和权重。同样给定一个表示背包容量的整数 W,找出 val[] 的最大值子集,使得这个子集的权重之和小于或等于 W。我们不能破坏一个项目,要么选择完整的项目,要么不不选择它(0-1 属性)。
这里 W <= 2000000 和 n <= 500
例子:
Input : W = 10, n = 3
val[] = {7, 8, 4}
wt[] = {3, 8, 6}
Output: 11
We get maximum value by picking items of 3 KG and 6 KG.
我们在这里讨论了基于动态规划的解决方案。在之前的解决方案中,我们使用了一个 * W 矩阵。我们可以减少使用的额外空间。优化背后的想法是,为了计算 mat[i][j],我们只需要前一行的解。在 0-1 Knapsack Problem 中,如果我们当前在 mat[i][j] 上并且我们包含第 i 个元素,那么我们将 j-wt[i] 移回前一行,如果我们排除当前元素,我们将移到第 j 列上一行。所以在这里我们可以观察到,我们一次只处理 2 个连续的行。
在下面的解决方案中,我们创建了一个大小为 2*W 的矩阵。如果 n 为奇数,则最终答案将在 mat[0][W] 处,如果 n 为偶数,则最终答案将在 mat[1][W] 处,因为索引从 0 开始。
C++
// C++ program of a space optimized DP solution for
// 0-1 knapsack problem.
#include
using namespace std;
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// mat[2][W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
// matrix to store final result
int mat[2][W+1];
memset(mat, 0, sizeof(mat));
// iterate through all items
int i = 0;
while (i < n) // one by one traverse each element
{
int j = 0; // traverse all weights j <= W
// if i is odd that mean till now we have odd
// number of elements so we store result in 1th
// indexed row
if (i%2!=0)
{
while (++j <= W) // check for each value
{
if (wt[i] <= j) // include element
mat[1][j] = max(val[i] + mat[0][j-wt[i]],
mat[0][j] );
else // exclude element
mat[1][j] = mat[0][j];
}
}
// if i is even that mean till now we have even number
// of elements so we store result in 0th indexed row
else
{
while(++j <= W)
{
if (wt[i] <= j)
mat[0][j] = max(val[i] + mat[1][j-wt[i]],
mat[1][j]);
else
mat[0][j] = mat[1][j];
}
}
i++;
}
// Return mat[0][W] if n is odd, else mat[1][W]
return (n%2 != 0)? mat[0][W] : mat[1][W];
}
// Driver program to test the cases
int main()
{
int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
cout << KnapSack(val, wt, n, W) << endl;
return 0;
}
Java
// Java program of a space optimized DP solution for
// 0-1 knapsack problem.
class GFG
{
// val[] is for storing maximum
// profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// mat[2][W+1] to store final result
static int KnapSack(int val[], int wt[],
int n, int W)
{
// matrix to store final result
int mat[][] = new int[2][W + 1];
// iterate through all items
int i = 0;
while (i < n) // one by one traverse each element
{
int j = 0; // traverse all weights j <= W
// if i is odd that mean till now we have odd
// number of elements so we store result in 1th
// indexed row
if (i % 2 != 0)
{
while (++j <= W) // check for each value
{
if (wt[i] <= j) // include element
{
mat[1][j] = Math.max(val[i] + mat[0][j - wt[i]],
mat[0][j]);
} else // exclude element
{
mat[1][j] = mat[0][j];
}
}
}
// if i is even that means till now
// we have even number of elements
// so we store result in 0th indexed row
else
{
while (++j <= W)
{
if (wt[i] <= j)
{
mat[0][j] = Math.max(val[i] + mat[1][j - wt[i]],
mat[1][j]);
} else
{
mat[0][j] = mat[1][j];
}
}
}
i++;
}
// Return mat[0][W] if n is odd, else mat[1][W]
return (n % 2 != 0) ? mat[0][W] : mat[1][W];
}
// Driver Code
public static void main(String[] args)
{
int val[] = {7, 8, 4},
wt[] = {3, 8, 6},
W = 10, n = 3;
System.out.println(KnapSack(val, wt, n, W));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python program of a space
# optimized DP solution for
# 0-1 knapsack problem.
# val[] is for storing maximum
# profit for each weight
# wt[] is for storing weights
# n number of item
# W maximum capacity of bag
# mat[2][W+1] to store final result
def KnapSack(val, wt, n, W):
# matrix to store final result
mat = [[0 for i in range(W + 1)]
for i in range(2)]
# iterate through all items
i = 0
while i < n: # one by one traverse
# each element
j = 0 # traverse all weights j <= W
# if i is odd that mean till
# now we have odd number of
# elements so we store result
# in 1th indexed row
if i % 2 == 0:
while j < W: # check for each value
j += 1
if wt[i] <= j: # include element
mat[1][j] = max(val[i] + mat[0][j -
wt[i]], mat[0][j])
else: # exclude element
mat[1][j] = mat[0][j]
# if i is even that mean till
# now we have even number
# of elements so we store
# result in 0th indexed row
else:
while j < W:
j += 1
if wt[i] <= j:
mat[0][j] = max(val[i] + mat[1][j -
wt[i]], mat[1][j])
else:
mat[0][j] = mat[1][j]
i += 1
# Return mat[0][W] if n is
# odd, else mat[1][W]
if n % 2 == 0:
return mat[0][W]
else:
return mat[1][W]
# Driver code
val = [7, 8, 4]
wt = [3, 8, 6]
W = 10
n = 3
print(KnapSack(val, wt, n, W))
# This code is contributed
# by sahilshelangia
C#
// C# program of a space optimized DP solution for
// 0-1 knapsack problem.
using System;
class GFG
{
// val[] is for storing maximum
// profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// mat[2,W+1] to store final result
static int KnapSack(int []val, int []wt,
int n, int W)
{
// matrix to store final result
int [,]mat = new int[2, W + 1];
// iterate through all items
int i = 0;
while (i < n) // one by one traverse each element
{
int j = 0; // traverse all weights j <= W
// if i is odd that mean till now we have odd
// number of elements so we store result in 1th
// indexed row
if (i % 2 != 0)
{
while (++j <= W) // check for each value
{
if (wt[i] <= j) // include element
{
mat[1, j] = Math.Max(val[i] + mat[0, j - wt[i]],
mat[0, j]);
} else // exclude element
{
mat[1,j] = mat[0,j];
}
}
}
// if i is even that means till now
// we have even number of elements
// so we store result in 0th indexed row
else
{
while (++j <= W)
{
if (wt[i] <= j)
{
mat[0, j] = Math.Max(val[i] + mat[1, j - wt[i]],
mat[1, j]);
}
else
{
mat[0, j] = mat[1, j];
}
}
}
i++;
}
// Return mat[0,W] if n is odd, else mat[1,W]
return (n % 2 != 0) ? mat[0, W] : mat[1, W];
}
// Driver Code
public static void Main(String[] args)
{
int []val = {7, 8, 4};
int []wt = {3, 8, 6};
int W = 10, n = 3;
Console.WriteLine(KnapSack(val, wt, n, W));
}
}
// This code is contributed by 29AjayKumar
PHP
Javascript
C++
// C++ program of a space optimized DP solution for
// 0-1 knapsack problem.
#include
using namespace std;
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
// array to store final result
//dp[i] stores the profit with KnapSack capacity "i"
int dp[W+1];
//initially profit with 0 to W KnapSack capacity is 0
memset(dp, 0, sizeof(dp));
// iterate through all items
for(int i=0; i < n; i++)
//traverse dp array from right to left
for(int j=W; j>=wt[i]; j--)
dp[j] = max(dp[j] , val[i] + dp[j-wt[i]]);
/*above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") */
return dp[W];
}
// Driver program to test the cases
int main()
{
int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
cout << KnapSack(val, wt, n, W) << endl;
return 0;
}
// This code is contributed by Gaurav Mamgain
Java
// Java program of a space optimized DP solution for
// 0-1 knapsack problem.
import java.util.Arrays;
class GFG
{
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
static int KnapSack(int val[], int wt[], int n, int W)
{
// array to store final result
//dp[i] stores the profit with KnapSack capacity "i"
int []dp = new int[W+1];
//initially profit with 0 to W KnapSack capacity is 0
Arrays.fill(dp, 0);
// iterate through all items
for(int i=0; i < n; i++)
//traverse dp array from right to left
for(int j = W; j >= wt[i]; j--)
dp[j] = Math.max(dp[j] , val[i] + dp[j - wt[i]]);
/*above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") */
return dp[W];
}
// Driver code
public static void main(String[] args)
{
int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
System.out.println(KnapSack(val, wt, n, W));
}
}
// This code is contributed by Princi Singh
Python3
# Python program of a space optimized DP solution for
# 0-1 knapsack problem.
# val[] is for storing maximum profit for each weight
# wt[] is for storing weights
# n number of item
# W maximum capacity of bag
# dp[W+1] to store final result
def KnapSack(val, wt, n, W):
# array to store final result
# dp[i] stores the profit with KnapSack capacity "i"
dp = [0]*(W+1);
# iterate through all items
for i in range(n):
#traverse dp array from right to left
for j in range(W,wt[i],-1):
dp[j] = max(dp[j] , val[i] + dp[j-wt[i]]);
'''above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") *'''
return dp[W];
# Driver program to test the cases
val = [7, 8, 4];
wt = [3, 8, 6];
W = 10; n = 3;
print(KnapSack(val, wt, n, W));
# This code is contributed by Princi Singh
C#
// C# program of a space optimized DP solution for
// 0-1 knapsack problem.
using System;
class GFG
{
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
static int KnapSack(int []val, int []wt, int n, int W)
{
// array to store final result
//dp[i] stores the profit with KnapSack capacity "i"
int []dp = new int[W + 1];
//initially profit with 0 to W KnapSack capacity is 0
for(int i = 0; i < W + 1; i++)
dp[i] = 0;
// iterate through all items
for(int i = 0; i < n; i++)
//traverse dp array from right to left
for(int j = W; j >= wt[i]; j--)
dp[j] = Math.Max(dp[j] , val[i] + dp[j - wt[i]]);
/*above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") */
return dp[W];
}
// Driver code
public static void Main(String[] args)
{
int []val = {7, 8, 4};
int []wt = {3, 8, 6};
int W = 10, n = 3;
Console.WriteLine(KnapSack(val, wt, n, W));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出:
11
时间复杂度: O(n * W)
辅助空间: O(W)
这是 Gaurav Mamgain 贡献的优化代码
C++
// C++ program of a space optimized DP solution for
// 0-1 knapsack problem.
#include
using namespace std;
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
// array to store final result
//dp[i] stores the profit with KnapSack capacity "i"
int dp[W+1];
//initially profit with 0 to W KnapSack capacity is 0
memset(dp, 0, sizeof(dp));
// iterate through all items
for(int i=0; i < n; i++)
//traverse dp array from right to left
for(int j=W; j>=wt[i]; j--)
dp[j] = max(dp[j] , val[i] + dp[j-wt[i]]);
/*above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") */
return dp[W];
}
// Driver program to test the cases
int main()
{
int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
cout << KnapSack(val, wt, n, W) << endl;
return 0;
}
// This code is contributed by Gaurav Mamgain
Java
// Java program of a space optimized DP solution for
// 0-1 knapsack problem.
import java.util.Arrays;
class GFG
{
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
static int KnapSack(int val[], int wt[], int n, int W)
{
// array to store final result
//dp[i] stores the profit with KnapSack capacity "i"
int []dp = new int[W+1];
//initially profit with 0 to W KnapSack capacity is 0
Arrays.fill(dp, 0);
// iterate through all items
for(int i=0; i < n; i++)
//traverse dp array from right to left
for(int j = W; j >= wt[i]; j--)
dp[j] = Math.max(dp[j] , val[i] + dp[j - wt[i]]);
/*above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") */
return dp[W];
}
// Driver code
public static void main(String[] args)
{
int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
System.out.println(KnapSack(val, wt, n, W));
}
}
// This code is contributed by Princi Singh
蟒蛇3
# Python program of a space optimized DP solution for
# 0-1 knapsack problem.
# val[] is for storing maximum profit for each weight
# wt[] is for storing weights
# n number of item
# W maximum capacity of bag
# dp[W+1] to store final result
def KnapSack(val, wt, n, W):
# array to store final result
# dp[i] stores the profit with KnapSack capacity "i"
dp = [0]*(W+1);
# iterate through all items
for i in range(n):
#traverse dp array from right to left
for j in range(W,wt[i],-1):
dp[j] = max(dp[j] , val[i] + dp[j-wt[i]]);
'''above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") *'''
return dp[W];
# Driver program to test the cases
val = [7, 8, 4];
wt = [3, 8, 6];
W = 10; n = 3;
print(KnapSack(val, wt, n, W));
# This code is contributed by Princi Singh
C#
// C# program of a space optimized DP solution for
// 0-1 knapsack problem.
using System;
class GFG
{
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
static int KnapSack(int []val, int []wt, int n, int W)
{
// array to store final result
//dp[i] stores the profit with KnapSack capacity "i"
int []dp = new int[W + 1];
//initially profit with 0 to W KnapSack capacity is 0
for(int i = 0; i < W + 1; i++)
dp[i] = 0;
// iterate through all items
for(int i = 0; i < n; i++)
//traverse dp array from right to left
for(int j = W; j >= wt[i]; j--)
dp[j] = Math.Max(dp[j] , val[i] + dp[j - wt[i]]);
/*above line finds out maximum of dp[j](excluding ith element value)
and val[i] + dp[j-wt[i]] (including ith element value and the
profit with "KnapSack capacity - ith element weight") */
return dp[W];
}
// Driver code
public static void Main(String[] args)
{
int []val = {7, 8, 4};
int []wt = {3, 8, 6};
int W = 10, n = 3;
Console.WriteLine(KnapSack(val, wt, n, W));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出:
11
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。