最简单的0-1背包问题c++代码实例及运行结果

一个容积为5的箱子,现在要装入物品,物品一共有4个,体积分别是1、2、3、4,问有几种填充方法

解析:每个物品最多装一次。很简单,只有两种1,4与2,3

c++代码

#include <iostream>

using namespace std;

int main()
{
    int array[]={1,2,3,4};
    int len=sizeof(array)/sizeof(array[0]);//数组长度
    int volume=5;
    int n=0;//记录组合次数
    cout<<"组合形式为:"<<endl;
    for(int i=0;i<len;i++)
        for(int j=i+1;j<len;j++)
            if(array[i]+array[j]==volume)
            {
                n++;
                cout<<"第"<<n<<"种组合形式为"<<array[i]<<" "<<array[j]<<endl;
            }
    return 0;
}


运行结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您解答这个问题。 0-1背包问题是动态规划问题中的一个经典问题,其目的是在给定一组物品和一个背包容量的情况下,选择一些物品放入背包中,使得背包中物品的总价值最大。而分支限界法是一种搜索算法,它可以通过优先队列来维护搜索状态空间中的结点,从而提高搜索效率。 下面是使用C++ STL最小堆来实现已搜索的解状态空间结点的优先级队列的代码: ```c++ #include <iostream> #include <vector> #include <queue> #include <algorithm> using namespace std; // 物品结构体 struct Item { int weight; // 物品重量 int value; // 物品价值 }; // 结点结构体 struct Node { int level; // 结点所在层数 int profit; // 当前背包中物品的总价值 int weight; // 当前背包中物品的总重量 vector<bool> solution; // 当前背包中物品的选择情况 double bound; // 当前结点的价值上界 bool operator<(const Node& other) const { // 重载小于号,用于STL最小堆排序 return bound < other.bound; } }; // 计算结点的价值上界 double calc_bound(const vector<Item>& items, const Node& node, int capacity) { double bound = node.profit; int weight = node.weight; int level = node.level; while (level < items.size() && weight + items[level].weight <= capacity) { bound += items[level].value; weight += items[level].weight; level++; } if (level < items.size()) { bound += (capacity - weight) * items[level].value / (double)items[level].weight; } return bound; } // 分支限界法求解0-1背包问题 int knapsack(const vector<Item>& items, int capacity) { // 按照单位重量的价值从大到小排序 vector<int> indices(items.size()); iota(indices.begin(), indices.end(), 0); sort(indices.begin(), indices.end(), [&items](int i, int j) { return items[i].value * 1.0 / items[i].weight > items[j].value * 1.0 / items[j].weight; }); // 初始化根结点 Node root = {0, 0, 0, vector<bool>(items.size(), 0), 0}; root.bound = calc_bound(items, root, capacity); // 初始化最小堆 priority_queue<Node> Q; Q.push(root); // 开始搜索 int max_profit = 0; while (!Q.empty()) { Node cur = Q.top(); Q.pop(); if (cur.bound < max_profit) { continue; } if (cur.level == items.size()) { max_profit = max(max_profit, cur.profit); continue; } // 选择当前物品 Node left = cur; left.level++; left.weight += items[indices[left.level - 1]].weight; left.profit += items[indices[left.level - 1]].value; left.solution[indices[left.level - 1]] = true; if (left.weight <= capacity) { left.bound = calc_bound(items, left, capacity); if (left.bound > max_profit) { Q.push(left); } } // 不选择当前物品 Node right = cur; right.level++; right.bound = calc_bound(items, right, capacity); if (right.bound > max_profit) { Q.push(right); } } return max_profit; } int main() { vector<Item> items = {{10, 60}, {20, 100}, {30, 120}}; int capacity = 50; int max_profit = knapsack(items, capacity); cout << "Max Profit: " << max_profit << endl; return 0; } ``` 在这个代码中,我们定义了一个`Item`结构体来存储物品的重量和价值信息,还定义了一个`Node`结构体来存储搜索状态空间中的结点信息。在`Node`结构体中,我们还重载了小于号运算符,这是为了让我们可以使用STL的最小堆来维护搜索结点的优先级。 在`calc_bound`函数中,我们计算了当前结点的价值上界,这是通过贪心的思路来计算的。具体来说,我们首先将当前结点的背包填满,然后尝试将下一个物品放入背包中,直到背包装不下为止。最后,我们将装不下的部分按照单位重量的价值比例来进行计算,从而得到当前结点的价值上界。 在`knapsack`函数中,我们使用了一个最小堆来维护搜索结点的优先级。在每一次循环中,我们取出最小堆中的顶部结点,然后根据当前结点的状态进行分支限界搜索。具体来说,我们分别考虑选择当前物品和不选择当前物品两种情况,然后计算子结点的价值上界,并将符合条件的子结点压入最小堆中。如果当前结点的价值上界小于已搜索到的最大价值,则可以剪枝,继续搜索下一个结点。 最后,在`main`函数中,我们定义了一个简单的0-1背包问题实例,然后调用`knapsack`函数求解,最终输出结果。 希望这个解答能够帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值