01背包,完全背包 C++

01背包问题是动态规划中一个经典的问题,也是背包问题的最基本形式之一。在01背包问题中,给定一个背包容量m和一组物品,每个物品有一个重量和一个价值。目标是选择物品放入背包中,使得背包中物品的总重量不超过m,且总价值最大。

01背包问题的特点是每个物品只有一个,要么选要么不选。可以通过构造一个二维数组dp[i][j]来表示前i个物品在背包容量为j时的最大总价值。其中,dp[i][j]的值表示在前i个物品中,能够装入容量为j的背包中的物品的最大总价值。

解决1维01背包问题的关键是构建一个一维的数组dp,其中dp[i]表示在背包容量为i时能获得的最大价值。

我们可以使用以下步骤来解决1维01背包问题:

1. 初始化dp数组为0。

2. 遍历每个物品,对于每个物品i,从容量C开始逆序遍历到该物品的重量w。对于每个容量j,如果j大于等于w,则可以将物品i放入背包,更新dp[j]为dp[j-w]+v和dp[j]中的较大值。

3. 最终,dp[m]即为在背包容量为C时能获得的最大价值。

#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
#define KUI ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
const int con = 2e5 + 4;
const int mod = 998244353;
int n, m, k, f[con], w[con], v[con];
void take()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> w[i] >> v[i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = m; j >= w[i]; j--)
        {
            f[j] = max(f[j], f[j - w[i]] + v[i]);
        }
    }
    cout << f[m];
}
int main()
{
    KUI;
    int t1 = 1;
    while (t1--)
    {
        take();
    }
    return 0;
}

完全背包问题是一个经典的动态规划问题。具体而言,给定一组商品,每个商品有一个重量和一个价值,以及一个背包的总容量,要求在不超过背包容量的情况下,选择商品,使得它们的总价值最大化。与0-1背包问题不同的是,完全背包问题可以选择重复使用某一种商品。

为了解决完全背包问题,可以使用动态规划的方法。我们定义一个二维数组dp[i][j],表示在背包容量为j的情况下,前i个商品能够达到的最大价值。那么,对于每一个商品i,我们可以选择使用0个、1个、2个……直至j/w[i]个该商品,其中w[i]表示商品的重量。因此,我们可以得到状态转移方程:

一维的完全背包问题可以使用动态规划来解决。假设有 n 个物品和一个容量为 V 的背包,物品的重量分别为 w1, w2, ..., wn,价值分别为 v1, v2, ..., vn。定义一个一维数组 dp,其中 dp[i] 表示容量为 i 的背包能够装下的最大价值。

初始条件是 dp[0] = 0,表示容量为 0 的背包的最大价值为 0。然后,对于每个物品 i,可以将其放入背包中,也可以不放入背包中。如果选择放入物品 i,那么背包的容量就减少了 wi,背包的价值就增加了 vi。因此,转移方程为:

dp[j] = max(dp[j], dp[j - wi] + vi)

其中,dp[j] 表示容量为 j 的背包能够装下的最大价值,dp[j - wi] 表示在放入物品 i 的情况下,容量为 j - wi 的背包能够装下的最大价值。考虑到物品 i 可以选择多次.

#include <bits/stdc++.h>
#define ll long long
#define endl "\n"
#define KUI ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
using namespace std;
const int con = 2e5 + 4;
const int mod = 998244353;
int n, m, k, f[con], w[con], v[con];
void take()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> w[i] >> v[i];
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = w[i]; j <= m; j++)
        {
            f[j] = max(f[j], f[j - w[i]] + v[i]);
        }
    }
    cout << f[m];
}
int main()
{
    KUI;
    int t1 = 1;
    while (t1--)
    {
        take();
    }
    return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值