多重背包(动态规划)

                                   题目B      剁手党                               限时:2000ms

剁手党们整天游荡在各种大小商场,有N种物品,每种物品的数量为C1,C2......Cn。从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的最大价值。

 

输入

第1行,2个整数,N和W中间用空格隔开。N为物品的种类,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000)

第2 - N + 1行,每行3个整数,Wi,Pi和Ci分别是物品体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)

 

输出

每组数据输出一行,即可以容纳的最大价值。

 

 

样例输入

样例输出

3 6

2 2 5

3 3 8

1 4 1

 

9

直观的多重背包

 

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>

using namespace std;

const int MAXN = 100 + 10;
int pri[MAXN], wei[MAXN], num[MAXN];
int dp[50010], sum, n;
void zeroOnePack(int price, int weight, int sum)    ///01背包
{
    for (int i = sum; i >= price; i--)
        dp[i] = max(dp[i], dp[i - price] + weight);
}
void completePack(int price, int weight, int sum)   ///完全背包
{
    for (int i = price; i <= sum; i++)
        dp[i] = max(dp[i], dp[i - price] + weight);
}
void multiPack(int n, int sum)          ///多重背包
{
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= n; i++)
    {
        if (pri[i] * num[i] > sum)      ///只买第i种大米可以将经费花完
            completePack(pri[i], wei[i], sum);  ///转化为完全背包等价于无限个可取
        else
        {
            for (int k = 1; k < num[i]; k *= 2) ///转化为01背包,系数为1,2,4...2^(k-1)
            {
                zeroOnePack(k * pri[i], k * wei[i], sum);
                num[i] -= k;
            }
            if (num[i] != 0)    ///最后剩余的袋数(num[i]-2^k+1)
                zeroOnePack(num[i] * pri[i], num[i] * wei[i], sum);
        }
    }
    printf("%d\n", dp[sum]);
}
void solve()
{
    while(~scanf("%d%d", &n, &sum))
    {
        for (int i = 1; i <= n; i++)
            scanf("%d%d%d", &pri[i], &wei[i], &num[i]);
        multiPack(n, sum);
    }
}
int main()
{
    solve();
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多重背包问题是指在一定的背包容量下,有多个物品的重量和价值,每个物品有一定的数量限制,要求在放入背包时,使得背包中物品的总价值最大化。动态规划是解决多重背包问题的一种常见方法。 其中,引用提供了一种将多重背包问题转化为01背包问题的方法。这种方法将每个多重背包问题的物品按照其数量进行拆分,使其变成多个01背包问题。然后使用动态规划的思想,依次求解每个01背包问题,最终得到多重背包问题的最优解。 引用提供了一种对完全背包问题的暴力解法做简单修改的方法。该方法同样使用动态规划的思想,对每个物品进行遍历,并在背包承重为j的前提下,求解每个物品能放入的最大数量。然后根据物品的重量和价值进行计算,得到多重背包问题的最优解。 这两种方法都可以用来解决多重背包问题,并根据实际情况选择合适的方法进行求解。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [动态规划(五):多重背包问题](https://blog.csdn.net/qq_42138662/article/details/118434151)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [动态规划多重背包问题](https://blog.csdn.net/qq_42174306/article/details/124345411)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [动态规划4:多重背包](https://blog.csdn.net/qq_40772692/article/details/81435230)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值