0

You are given weights and values of N items, put these items in a knapsack of capacity W to get the maximum total value in the knapsack. Note that we have only one quantity of each item.
In other words, given two integer arrays val[0..N-1] and wt[0..N-1] which represent values and weights associated with N items respectively. Also given an integer W which represents knapsack capacity, find out the maximum value subset of val[] such that sum of the weights of this subset is smaller than or equal to W. You cannot break an item, either pick the complete item, or don’t pick it (0-1 property).

Example 1:

Input:
N = 3
W = 4
values[] = {1,2,3}
weight[] = {4,5,1}
Output: 3

Example 2:

Input:
N = 3
W = 3
values[] = {1,2,3}
weight[] = {4,5,6}
Output: 0

Your Task:
Complete the function knapSack() which takes maximum capacity W, weight array wt[], value array val[] and number of items n as a parameter and returns the maximum possible value you can get.

Expected Time Complexity: O(N*W).
Expected Auxiliary Space: O(N*W)

Constraints:
1 ≤ N ≤ 1000
1 ≤ W ≤ 1000
1 ≤ wt[i] ≤ 1000
1 ≤ v[i] ≤ 1000

思路:

  0-1背包的基本思想是先对背包进行划分,然后将物品逐个的放入到背包中,如果背包当前的空间能够装得下该物品,则要分两种情况进行讨论:

  • 如果该物品放入背包后,剩余的空间还可以对上一个物品放入或者不放入背包进行讨论,因为在这种情况下只有背包的空间改变了,其余的都没有改变,所以可以看成原来问题的子问题来进行解决。
  • 如果该物品没有放入背包中,仍然需要对上一个物品进行讨论  

状态转移方程:

  • if w < wt[i]: dp[i][j] = dp[i-1][j]
  • else : dp[i][j] = max(dp[i-1][j], val[i] + dp[i-1][w - wt[i]]

代码:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int n, w;
    cin >> n >> w;
    vector<int> values(n);
    vector<int> weight(n);
    int t1, t2;
    for (int i = 0; i < n; ++i) {
        cin >> t1;
        values[i] = t1;
    }
    for (int i = 0; i < n; ++i) {
        cin >> t2;
        weight[i] = t2;
    }
    vector<vector<int> > dp(n + 1, vector<int>(w + 1, 0));
    for (int j = 1; j <= w; ++j) {
        if (j >= weight[0]) dp[0][j] = values[0];
    }
    for (int i = 1; i < n; ++i) {
        for (int j = 1; j <= w; ++j) {
            if (j >= weight[i]) {
                int temp = j - weight[i];
                dp[i][j] = max(values[i] + dp[i - 1][temp], dp[i - 1][j]);
            } else {
                dp[i][j] = dp[i - 1][j];
            }
        }
    }
    cout << dp[n - 1][w] << endl;
    return 0;
}
永远渴望,大智若愚(stay hungry, stay foolish)
原文地址:https://www.cnblogs.com/h-hkai/p/14683476.html