01背包怎么不重复_带有重复物品的背包

01背包怎么不重复

Problem statement:

问题陈述:

Weights and values are given for n items along with the maximum capacity allowed W. What is the maximum value we can achieve if we can pick any weights, any number of times for the total allowed capacity of W?

给出了n个项目的权重和值以及允许的最大容量W。 如果可以为W的总允许容量选择任意权重,任意次数,我们可以实现的最大值是多少?

Input:

输入:

First line contains two integers N and W denoting the number of items and the total allowed weight.

第一行包含两个整数NW,分别表示项目数和允许的总重量。

In the next two lines are space separated values of the array denoting values of the items val[n] and their weights weights[n] respectively.

在接下来的两行中,数组的空格分隔值分别表示项val [n]的值及其权重weight [n]

Output:

输出:

Output the maximum value which we can achieve if we can pick any weights any number of times for a total weight capacity of W.

如果我们可以选择任意数量的砝码来获得总重量W,则输出可以达到的最大值。

Constraints:

限制条件:

1 <= N,W <= 100
1 <= weight[i], val[i] <= 100

Example:

例:

Test case: 1

Input:
N=2,W= 3
val[]=1 1
weight[]=2 1 

Output:
Maximum value that can be achieved: 3

Test case: 2

Input:
N=3,W= 4
val[]=2 5 3
weight[]=1 2 1

Output:
Maximum value that can be achieved: 12

Explanation:

说明:

For the first test case,
Will use the second item with weight 1 only. 
We use will 3 such item to have maximum value 3.
Any other combinations will give less value

For the second test case,
Some possible combinations can be
Writing as (value, weight) pair
(2,1), (2,1), (2,1), (2,1)- total weight 4, value 8 
(2,1), (2,1), (5,2) - total weight 4, value 9
...
(3,1),(3,1), (3,1),(3,1)- total weight 4, value 12

The last combination is the most optimal one 
and that's produces the maximum.

Solution Approach:

解决方法:

The difference between this problem and the general knapsack problem is here we can use the same item several times. So the simple recursion about either choosing an item or leaving the item will not work here as using the same item may lead to the most optimized solution.

这个问题和一般背包问题之间的区别在于,我们可以多次使用同一项目。 因此,关于选择一个项目或离开该项目的简单递归在这里不起作用,因为使用同一项目可能会导致最优化的解决方案。

Hence, the algorithm will be like following,

因此,该算法将如下所示,

  1. Initialize a dp[w+1] to store for each sub-problem up to total capacity W.

    初始化dp [w + 1]为每个子问题存储直到总容量W。

  2. Reset all the values to zero initially.

    最初将所有值重置为零。

    memset(dp,0,sizeof(dp));

    memset(dp,0,sizeof(dp));

  3. Fill up the DP table with base value dp[0]=0,

    用基本值dp [0] = 0填充DP表,

    for sub-problem weight,i=1 to w
        for a weight,wj in the weight array
            if i>=wj
                dp[i] = std∷max⁡(dp[i],dp[i-wj]+valj)
            end if
        end for
    end for
    
    
  4. Maximum value that can be achieved is dp[w]

    可以达到的最大值是dp [w]

Let's compute the above for our test case two,

让我们为测试案例二计算以上内容,

N = 3, W = 4
val[] = 2 5 3
weight[] = 1 2 1

Initially the DP table is,

最初,DP表是

knapsack with duplicate items (1)

To compute dp[1],

要计算dp [1],

weight[0]<=1

So, 
dp[1] = max(dp[1],dp[1-1]+val[0]) = 2

Weight[1]>1. So it can't have any role while computing DP[1]
Weight[2]<=1

So, 
dp[1] = max(dp[1],dp[1-1]+val[2]) = 3

Similar way you can hand compute the DP table to understand how the algo is performing is reaching to the optimal answer.

您可以用类似的方法手工计算DP表,以了解算法的性能如何达到最佳答案。

The final DP table for the above test case would look like,

上述测试用例的最终DP表如下所示:

knapsack with duplicate items (2)

Where 12 is the final case.

最后的情况是12。

C++ Implementation:

C ++实现:

#include <bits/stdc++.h>
using namespace std;

void print(vector<int> a, int n)
{
    for (int i = 0; i < n; i++)
        cout << a[i] << " ";
    cout << endl;
}

int my(vector<int> price, vector<int> weight, int n, int w)
{

    int dp[w + 1];
    memset(dp, 0, sizeof(dp));

    for (int i = 1; i <= w; i++) {
        for (int j = 1; j <= n; j++) {
            if (i >= weight[j - 1])
                dp[i] = std::max(dp[i], dp[i - weight[j - 1]] + price[j - 1]);
        }
    }

    return dp[w];
}

int main()
{
    int n, item, w;

    cout << "enter number of item and total weights\n";
    cin >> n >> w;

    cout << "Enter the prices\n";
    vector<int> price;

    for (int j = 0; j < n; j++) {
        scanf("%d", &item);
        price.push_back(item);
    }

    cout << "Enter the weights\n";
    vector<int> weight;

    for (int j = 0; j < n; j++) {
        scanf("%d", &item);
        weight.push_back(item);
    }

    cout << "result is: " << my(price, weight, n, w) << endl;

    return 0;
}

Output:

输出:

enter number of item and total weights
3 4
Enter the prices
2 5 3
Enter the weights
1 2 1
result is: 12


翻译自: https://www.includehelp.com/icp/knapsack-with-duplicate-items.aspx

01背包怎么不重复

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值