博客
关于我
好理解的基于二叉树的0-1背包求解问题
阅读量:495 次
发布时间:2019-03-07

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

建立一个二叉树,我们约定左结点表示选择装入物品,右结点表示不装入物品。假设有5个物品,物品重量是{2, 2, 6, 5, 4},对应价值是{6, 3, 5, 4, 6}。背包的容量为10。

对于第一个物品,我们可以选择装入或者不装入。若装入,总重量为2,总价值为6。若不装入,总重量为0,总价值为0。

对于第二个物品,我们可以选择装入或者不装入。若第一个物品已经装入,则若装入第二个物品,总重量为4,总价值为9。若不装入第二个物品,总重量为2,总价值为6。若第一个物品没有装入,则若装入第二个物品,总重量为2,总价值为3。若不装入第二个物品,总重量为0,总价值为0。

依此类推,我们可以构造出这样的二叉树。通过先序遍历,即可获得背包中物品的最大总价值。

在代码实现中,我们可以使用递归的方式构建二叉树,并在遍历过程中记录最大价值。每次处理一个节点时,计算当前路径的总重量和价值。如果总重量超过背包容量,则返回空,否则继续处理左右子节点。处理完所有节点后,返回最大价值。

以下是代码示例:

#include 
#include
using namespace std;typedef struct TreeNode { long long int val; long long int weight; bool left; bool right; TreeNode *LChild; TreeNode *RChild; TreeNode *Parent;} TreeNode;TreeNode *init(TreeNode *node) { node->weight = 0; node->val = 0; node->left = false; node->right = false; node->LChild = NULL; node->RChild = NULL; node->Parent = NULL; return node;}TreeNode *addNode(TreeNode *parented, int w, int val) { TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode)); node = init(node); if (parented->weight + w <= c) { node->weight = w + parented->weight; node->val = val + parented->val; node->Parent = parented; } else { node = NULL; } return node;}int main(int argc, char const *argv[]) { TreeNode *head = (TreeNode *)malloc(sizeof(TreeNode)); head = init(head); int n, c; cin >> n >> c; int w[1001], p[1001]; for (int i = 0; i < n; i++) { cin >> w[i] >> p[i]; } head = init(head); int i = 0; while (1) { if (head->left && head->right && head->Parent == NULL) { cout << "结束" << endl; break; } if (head->left && head->right) { cout << "回退" << endl; i--; head = head->Parent; continue; } if (i >= n || head->weight >= c) { cout << "加完数据了或者已经装满了" << endl; if (MAX < head->val) { MAX = head->val; } head->left = true; head->right = true; continue; } if (!head->left) { cout << "加左结点 i = " << i << endl; head->left = true; head->LChild = addNode(head, w[i], p[i]); if (head->LChild != NULL) { i++; head = head->LChild; } } else if (!head->right) { cout << "加右结点 i = " << i << endl; head->right = true; head->RChild = addNode(head, 0, 0); if (head->RChild != NULL) { i++; head = head->RChild; } } } cout << MAX << endl;}

通过先序遍历,我们可以找到背包中物品的最大总价值。代码中使用了递归的方式构建二叉树,并在遍历过程中记录最大价值。每次处理一个节点时,计算当前路径的总重量和价值。如果总重量超过背包容量,则返回空,否则继续处理左右子节点。处理完所有节点后,返回最大价值。

在实际应用中,可以根据需要调整递归深度和性能优化措施,确保程序能够高效运行。

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

你可能感兴趣的文章
MySQL数据库与Informix:能否创建同名表?
查看>>
MySQL集群解决方案(4):负载均衡
查看>>
MySQL高级-视图
查看>>
nacos集群搭建
查看>>
Nessus漏洞扫描教程之配置Nessus
查看>>
Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
查看>>
Netpas:不一样的SD-WAN+ 保障网络通讯品质
查看>>
Netty WebSocket客户端
查看>>
Netty工作笔记0011---Channel应用案例2
查看>>
Netty工作笔记0014---Buffer类型化和只读
查看>>
Netty工作笔记0050---Netty核心模块1
查看>>
Netty工作笔记0084---通过自定义协议解决粘包拆包问题2
查看>>
Netty常见组件二
查看>>
netty底层源码探究:启动流程;EventLoop中的selector、线程、任务队列;监听处理accept、read事件流程;
查看>>
Netty核心模块组件
查看>>
Netty框架的服务端开发中创建EventLoopGroup对象时线程数量源码解析
查看>>
Netty源码—2.Reactor线程模型一
查看>>
Netty源码—4.客户端接入流程一
查看>>
Netty源码—4.客户端接入流程二
查看>>
Netty源码—5.Pipeline和Handler一
查看>>