01背包问题

16 篇文章 0 订阅

#dp动态规划01背包问题

首先我们先了解一下动态规划问题主要将的是什么:
有 NN 件物品和一个容量为 V 的背包,每件物品有各自的价值且只能被选择一次,要求在有限的背包容量下,装入的物品总价值最大。
「0-1 背包」是较为简单的动态规划问题,也是其余背包问题的基础。
动态规划是不断决策求最优解的过程,「0-1 背包」即是不断对第 ii 个物品的做出决策,「0-1」正好代表不选与选两种决定。

背包问题可以分为两个步骤:一个是状态表示,一个是状态计算。状态表示和计算我们可以用一个二维数组分f[N][N] 表示,其中N是问题中物品的最大数量,每一个状态可以用f[i][j] 来表示其中i表示前 i 个物品并且体积不超过 j 的最优解。

当前的状态依赖于之前的状态,可以理解为从初始状态f[0][0] = 0开始决策,有 NN 件物品,则需要 NN 次决 策,每一次对第 ii 件物品的决策,状态f[i][j]不断由之前的状态更新而来。
(1)当前背包容量不够(j < v[i]),没得选,因此前 ii 个物品最优解即为前 i−1i−1 个物品最优解:

对应代码:f[i][j] = f[i - 1][j]。
(2)当前背包容量够,可以选,因此需要决策选与不选第i 个物品:

选:f[i][j] = f[i - 1][j - v[i]] + w[i]。
不选:f[i][j] = f[i - 1][j] 。
我们的决策是如何取到最大价值,因此以上两种情况取 max()

v输入存的是每件物品的体积,w数组存的是每件物品的价值。

下面是完整代码:

  #include <iostream>
  #include  <cstring>
  #include  <algorithm>
  using namespace std;
 const int N=1010;
 int f[N][N];
 int v[N];
  int w[N];
 int n,m;
  int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>v[i];
        cin>>w[i];
    }
    
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            f[i][j]=f[i-1][j];
            if(j>=v[i])  f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
            
        }
    }
    cout<<f[n][m];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值