# 【DP算法篇之初学】背包问题

3639人阅读 评论(1)

### 0 1 背包

有n个物品，每个物品的重量为w[i]，每个物品的价值为v[i]。现在有一个背包，它所能容纳的重量为W，问：当你面对这么多有价值的物品时，你的背包所能带走的最大价值是多少？

c[0..W]，能不能保证第 i 次循环结束后 c[w] 中表示的就是我们定义的状态 c[i][w] 呢？ c[i][w] 是由 c[i - 1][w] 和 c[i-1][w - c[i]] 两个

for i = 1..n
for w = W..0
c[w] = max{c[w], c[w - w[i]] + v[i]};

procedure ZeroOnePack(weight, value)
for w = W..weight
c[w] = max{c[w], c[w - weight] + value}

for i=1..N
ZeroOnePack(w[i], v[i]);

### 完全背包

c[i][w] = max{c[i - 1][w - k * w[i]] + k * v[i] | 0 <= k * w[i] <= w}

## O(Wn)的算法

for i = 1..n
for w = 0..W
c[w]=max{c[w], c[w - w[i]] + v[i]}

c[i - 1][w - w[i]] 。而现在完全背包的特点恰是每种物品可选无限件，所以在考虑“加选一件第 i 种物品”这种策略时，却正需要一个可

procedure CompletePack(weight, value)
for w = weight..W
c[w] = max{c[w], c[w - weight] + value}

### 多重背包

1、Backpack

Given n items with size Ai, an integer m denotes the size of a backpack.
How full you can fill this backpack?

Example
If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select [2, 3, 5],
so that the max size we can fill this backpack is 10. If the backpack size is 12.
we can select [2, 3, 7] so that we can fulfill the backpack.

You function should return the max size we can fill in the given backpack.

res[i][j] = max{res[i - 1][j - w[i]] + w[i], res[i - 1][j]}

res[j] = max{res[j - w[i]] + w[i], res[j]}

class Solution {
public:
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
int backPack(int m, vector<int> A) {
int n = A.size(), i, j;
vector<int> res(m + 1);

for(i = 0; i < n; ++i)
{
for(j = m; j >= A[i]; --j)
{
res[j] = max(res[j - A[i]] + A[i], res[j]);
}
}

return res[m];
}
};

Given n items with size Ai and value Vi, and a backpack with size m.
What's the maximum value can you put into the backpack?

Example
Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4], and a backpack with size 10. The maximum value is 9.

class Solution {
public:
/**
* @param m: An integer m denotes the size of a backpack
* @param A & V: Given n items with size A[i] and value V[i]
* @return: The maximum value
*/
int backPackII(int m, vector<int> A, vector<int> V) {
int n = A.size(), i, j;
vector<int> res(m + 1);

for(i = 0; i < n; ++i)
{
for(j = m; j >= A[i]; --j)
{
res[j] = max(res[j - A[i]] + V[i], res[j]);
}
}

return res[m];
}
};

Given an integer array nums with all positive numbers and no duplicates, find the number of
possible combinations that add up to a positive integer target.

Example
Given nums = [1, 2, 4], target = 4

The possible combination ways are:
[1, 1, 1, 1]
[1, 1, 2]
[1, 2, 1]
[2, 1, 1]
[2, 2]
[4]

return 6

class Solution {
public:
/**
* @param nums an integer array and all positive numbers, no duplicates
* @param target an integer
* @return an integer
*/
int backPackVI(vector<int>& nums, int target) {
int n = nums.size(), i, j;
vector<int> res(target + 1);
res[0] = 1;

for(i = 1; i <= target; ++i)
{
for(j = 0; j < n; ++j)
{
if(nums[j] <= i)
{
res[i] += res[i - nums[j]];
}
}
}

return res[target];
}
};


1
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：99215次
• 积分：2199
• 等级：
• 排名：第19849名
• 原创：121篇
• 转载：7篇
• 译文：0篇
• 评论：19条
博客专栏
 《Effective C++》学习笔记 文章：13篇 阅读：4447
 Xv6操作系统 文章：14篇 阅读：24372
最新评论