博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【算法概论】动态规划:背包问题
阅读量:4177 次
发布时间:2019-05-26

本文共 2280 字,大约阅读时间需要 7 分钟。

0 - 1背包问题

问题描述:

       给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为W(假定物品重量与背包容量值均为整数),应如何选择装入背包中的物品,使得装入背包中物品的总价值最大?设计一个动态规划算法,求解背包问题。

❗算法描述❗:

定义 w[] 存储各物品的重量,v[] 存储各物品的价值,背包的重量为 wsum。

①定义子问题:

       k(w, j) = 容量剩余 w 时,从物品 1 到 j 能得到的最高价值。

②是否满足最优子结构:

       k(w, j) = max( k(w - wj, j-1) + vj,k(w, j-1));

       前者指,第 j 个物品放入背包中,则产生的最高价值就是,在背包容量为 w-wj 的情况下,在 0 ~ j-1 这些物品中能产生的最高价值 + 第 j 个物品 的价值;

       后者指,第 j 个物品不放入背包中,则产生的最高价值就是,背包容量还剩 w,在0 ~ j-1 这些物品中能产生的最高价值。

       所以,

|    0, if w == 0 or j = 0k(w, j) = |    k(w, j-1), if w < wj          |    max( k( w - wj, j - 1) + vj, k(w, j-1)), otherwise

③确定解决子问题的次序:

       自底向上,bottom - up。

④回溯最优解:

代码如下:

#include 
#include
using namespace std;int max(int, int);void knapsack(vector
> k, vector
w, vector
v, int c, int num);int main(){ int num; cout << "请输入物品个数:" << endl; cin >> num; vector
w(num + 1, 0); vector
v(num + 1, 0); cout << "请输入各物品的重量:" << endl; for (int i = 1; i < num + 1; ++i) { cin >> w[i]; } cout << "请输入各物品的价值:" << endl; for (int i = 1; i < num + 1; ++i) { cin >> v[i]; } int c; cout << "请输入背包的容量:" << endl; cin >> c; vector
> k(c + 1, vector
(num + 1)); for (int i = 0; i < c; ++i) { k[i][0] = 0; } for (int j = 0; j < num; ++j) { k[0][j] = 0; } for (int j = 1; j < num + 1; ++j) { for (int i = 0; i < c + 1; ++i) { //如果背包的剩余容量小于第 j 个物品的重量 if (i < w[j]) { k[i][j] = k[i][j - 1]; } //否则 else { k[i][j] = max(k[i - w[j]][j - 1] + v[j], k[i][j - 1]); } } } cout << "背包可能容纳物品的最大价值:" << endl; cout << k[c][num] << endl; knapsack(k, w, v, c, num); cout << endl; return 0;}//回溯结果void knapsack(vector
> k, vector
w, vector
v, int c, int num){ if (c >= w[1] && num > 0) { if (k[c][num] == k[c - w[num]][num - 1] + v[num]) { cout << num << ' '; knapsack(k, w, v, c - w[num], num - 1); } else if (k[c][num] == k[c][num - 1]) { knapsack(k, w, v, c, num - 1); } } else { return; }}int max(int a, int b){ return a > b ? a : b;}

 

一篇有趣的讲解:

一篇全面的讲解:

转载地址:http://httai.baihongyu.com/

你可能感兴趣的文章
Docker容器支持IPv6的方法
查看>>
Can not deserialize instance of java.lang.String out of START_OBJECT token
查看>>
JTF的Unable to invoke request异常或Unable to find a MessageBodyReader of content-type application..异常详解
查看>>
JavaNCSS概述及JavaNCSS got an error while parsing the java file详解
查看>>
openssh-client amd64 1:7.2p2-4ubuntu2.4 404 Not Found
查看>>
Rapidoid及其容器化的Web平台
查看>>
JavaEE的JSON API规范JSON-P/JSON-B
查看>>
Kubernetes及其Master/Node节点
查看>>
OpenStack Heat简介
查看>>
Kubernetes集群内外的网络连通性
查看>>
TestNG中的@Factory与@DataProvider的执行比较
查看>>
TestNG中在一个test标签中的多个测试类之间共享中间数据的方法
查看>>
TestNG中在一个suite标签中的多个test标签之间共享中间数据的方法
查看>>
Docker容器实例的网络与通信
查看>>
OpenStack的Telemetry Data Collection服务概述
查看>>
iptables及其过滤规则
查看>>
基于iptables的Docker网络隔离与通信详解
查看>>
Linux内核的网络命名空间的概念及常用命令
查看>>
虚拟网络设备及其在Linux网络命名空间中的应用
查看>>
NAT及跨网络命名空间的网络地址转换
查看>>