背包问题

本文通过一个具体的例子介绍了如何使用动态规划解决背包问题。通过二维数组记录每个子问题的解,递推公式为f[i][j]=max(f[i-1][j], f[i-1][j-w[i]]+v[i]),并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#include <iostream>
using namespace std;

// 参考 http://baike.baidu.com/link?url=kOn5J1ionfV40_l4SagPK3aO6vu6TAB4r9iPociRXEm6R0Er8JEb4wpE2_53GJe8vPQ-KLb8-Au6r3N4K8h6PDpxqMhyEkxWxZoFWcqlqfZhZJCjuFTVixTVbZx1Fzu7

void check(int n, int *w, int *v, int C, int **f){
  // 放置第1个
  for (int i = 0; i < C + 1; ++i){
    if(w[0] <= i)
      f[0][i] = v[0];
    else
      f[0][i] = 0;
  }

  // 放置后n-1个
  for (int i = 1; i < n; ++i){
    for (int j = 0; j < C + 1; ++j){
      if(w[i] > j)
        f[i][j] = f[i - 1][j];
      else
        // 不放置第i个物品 f[i][j] = f[i - 1][j]
        // 放置第i个物品 f[i][j] = f[i - 1][j - w[i]] + v[i]
        f[i][j] = f[i - 1][j] > (f[i - 1][j - w[i]] + v[i]) ? f[i - 1][j] : (f[i - 1][j - w[i]] + v[i]);
    }
  }
}

void solution(int n, int *v, int C, int **f, int *s){
  // 第1个物品是否应该装入
  if (f[0][C])
    s[0] = 1;

  // 后n-1个是否应该装入
  for (int i = 1; i < n; ++i){
    if(f[i][C] == f[i - 1][C])
      s[i] = 0;
    else
      s[i] = 1;
  }
}

int main()  
{
  int n = 5;  // 物品总数
  int w[]={2, 2, 6, 5, 4};  // 重量
  int v[]={6, 3, 5, 4, 6};  // 价值
  int C = 10; // 背包容量

  // f[i][j]表示前i个物品装入容量j的背包时的最大价值
  int **f = new int*[n];
  for (int i = 0; i < n; ++i){
    f[i] = new int[C + 1];
  }
  // s[i]表示最终第i个物品是否应该装入
  int *s = new int[n];

  check(n, w, v, C, f);
  solution(n, v, C, f, s);

  cout << "最优方案:\n";
  for (int i = 0; i < n; ++i){
    cout << s[i] << " ";
  }
  cout << "\n总价值:\n";
  cout << f[n - 1][C] << endl;;

  int ttt = 0;  
  return 0;  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值