博客
关于我
好理解的基于二叉树的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/

你可能感兴趣的文章
OA系统选型:选择好的工作流引擎
查看>>
OA让企业业务流程管理科学有“据”
查看>>
OA项目之会议通知(查询&是否参会&反馈详情)
查看>>
Vue.js 学习总结(13)—— Vue3 version 计数介绍
查看>>
OA项目之我的会议(会议排座&送审)
查看>>
OA项目之我的会议(查询)
查看>>
OA项目之我的审批(会议查询&会议签字)
查看>>
OA项目之项目简介&会议发布
查看>>
ObjC的复制操作
查看>>
Object c将一个double值转换为时间格式
查看>>
object detection之Win10配置
查看>>
object detection训练自己数据
查看>>
object detection错误Message type "object_detection.protos.SsdFeatureExtractor" has no field named "bat
查看>>
object detection错误之Could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERROR
查看>>
object detection错误之no module named nets
查看>>
Object of type 'ndarray' is not JSON serializable
查看>>
Object Oriented Programming in JavaScript
查看>>
object references an unsaved transient instance - save the transient instance before flushing
查看>>
Object 类的常见方法有哪些?
查看>>
Object-c动态特性
查看>>