Dynamic Programming part 1 -- Knapsack Problem

本文介绍了动态规划在解决资源受限选择任务中的应用,特别是背包问题。分为允许重复和不允许重复两种情况讨论。通过动态规划,可以在O(nW)的时间复杂度内求解,其中n是物品数量,W是背包容量。对于允许重复的情况,问题转化为在DAG中寻找最长路径;而不允许重复的情况下,需额外记录物品使用情况,填充二维表格求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

This article is adapted from this pdf.

During a robbery, a burglar finds much more loot than he had expected and has to decide what to take. His bag (or “knapsack”) will hold a total weight of at most W pounds. There are n items to pick from, of weight w1,...,wn and dollar value v1,...,vn . What’s the most valuable combination of items he can fit into his bag?

If this application seems frivolous, replace “weight” with “CPU time” and “only W pounds can be taken” with “only W units of CPU time are available.” Or use “bandwidth” in place of “CPU time,” etc. The knapsack problem generalizes a wide variety of resource-constrained selection tasks.
For instance, take W = 10 and

Item Weight Value
1 6 $30
2 3 $14
3 4 $16
4 2 $9

There are two versions of this problem. If there are unlimited quantities of each item available, the optimal choice is to pick item 1 and two of item 4 (total: $48). On the other hand, if there is one of each item (the burglar has broken into an art gallery, say), then the optimal knapsack contains items 1 and 3 (total: $46). 这个问题有两个版本,如果每个item的数量不限, 最优的方案是取1个1和2个4,共48元; 如果每个item的数量只有一个,最优的方案是1和3各取一个,共46元

As we shall see in Chapter 8, neither version of this problem is likely to have a polynomial time algorithm. However, using dynamic programming they can both be solved in O(nW) time, which is reasonable when W is small, but is not polynomial since the input size is proportional to logW rather than W .

Knapsack with repetition

Let’s start with the version that allows repetition. As always, the main question in dynamic programming is, what are the subproblems? In this case we can shrink the original problem in two ways: we can either look at smaller knapsack capacities w ≤ W, or we can look at fewer items (for instance, items 1, 2, … , j, for j ≤ n). It usually takes a little experimentation to figure out exactly what works. 怎么找子问题呢?可以从两个方面二选一入手: 更小的背包或者更少的物品

The first restriction calls for smaller capacities. Accordingly, define

K(w)=maximum value achievable with a knapsack of capacity w.
The 0-1 Knapsack Problem is a classic optimization problem in computer science and mathematics. The problem is as follows: Given a set of items, each with a weight and a value, determine the items to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. The 0-1 indicates that each item can only be included once or not at all. This problem can be solved using dynamic programming. We can create a two-dimensional array where the rows represent the items and the columns represent the weight limit. For each item and weight limit, we can calculate the maximum value that can be obtained by either including the item or excluding it. We can then fill in the array row by row until we reach the final row, which represents the optimal solution. Here is an example implementation of the 0-1 Knapsack Problem in Java: ``` public class Knapsack { public static int knapsack(int[] values, int[] weights, int limit) { int[][] dp = new int[values.length + 1][limit + 1]; for (int i = 1; i <= values.length; i++) { for (int j = 1; j <= limit; j++) { if (weights[i-1] > j) { dp[i][j] = dp[i-1][j]; } else { dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-weights[i-1]] + values[i-1]); } } } return dp[values.length][limit]; } public static void main(String[] args) { int[] values = {60, 100, 120}; int[] weights = {10, 20, 30}; int limit = 50; int result = knapsack(values, weights, limit); System.out.println("Maximum value: " + result); } } ``` In this example, we have three items with values of 60, 100, and 120 and weights of 10, 20, and 30, respectively. We want to find the maximum value we can obtain with a weight limit of 50. The result is 220, which indicates that we should select items 2 and 3 to maximize the value while staying under the weight limit.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值