概述
问题描述:给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为C。应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?每种物品只有一个
解题思路:有了遍历n维0/1数组的方法,我们可以直接遍历所有的结果,记录价值最大时的拿取方案,详见我的上一篇文章。
直接上代码:
//给定n种物品和一个背包。物品i的重量是wi,其价值为vi,背包的容量为C。应该如何选择装入背包中的物品,使得装入背包中物品的总价值最大?
//有了遍历n维0/1数组的方法,我们可以直接遍历所有的结果,记录价值最大时的拿取方案
#include "pch.h"
#include <iostream>
#include <vector>
using namespace std;
//给出拿取情况向量与重量列表向量,求解当前背包重量
int CalculateWeight(vector<int> taken_items, vector<int> weights)
{
int weight = 0;
for (int i = 0; i < taken_items.size(); i++)
weight = weight + taken_items[i] * weights[i];
return weight;
}
//递归实现n维0/1数组的取值情况遍历
//使用时vec初始化为全零数组,i初始化为0,递归前先进行一次operation
//递归时vec的第i个元素进行变化
void BackpackProblem(vector<int> taken_items, int i, int capacity, vector<int> weights, vector<int> values, vector<int> &solution, int* solution_value)
{
//如果i超出taken_items范围,则返回
if (i == taken_items.size())
return;
//如果超出背包重量,则返回
if (CalculateWeight(taken_items, weights) > capacity)
return;
//递归
BackpackProblem(taken_items, i + 1, capacity, weights, values, solution, solution_value);
//变化第i个元素,进行操作
taken_items[i] = 1;
//operation
//计算当前价值并与最佳价值比较,如果当前方案更优就取当前方案,更新两个量
int current_value = CalculateWeight(taken_items, values);
if (current_value > *solution_value)
{
solution = taken_items;
*solution_value = current_value;
}
//递归
BackpackProblem(taken_items, i + 1, capacity, weights, values, solution, solution_value);
}
//根据拿取情况向量输出结果
void PrintResult(vector<int> taken_items, int best_value)
{
cout << "【最优解】拿取第";
for (int i = 0; i < taken_items.size(); i++)
if (taken_items[i])cout << i << ' ';
cout <<"个物品"<< endl;
cout << "【最优解】最大价值为:" << best_value << endl;
}
int main()
{
//初始化
int capacity;
vector<int> weights;
vector<int> values;
int number;
cout << "输入背包容量及物品件数:" << endl;
cin >> capacity >> number;
cout << "输入这" << number << "个物品的重量" << endl;
for (int i = 0; i < number; i++)
{
int weight;
cin >> weight;
weights.push_back(weight);
}
cout << "输入这" << number << "个物品的价值" << endl;
for (int i = 0; i < number; i++)
{
int value;
cin >> value;
values.push_back(value);
}
//定义拿取情况向量
vector<int> taken_items(number, 0);
//定义最佳拿取情况向量
vector<int> solution(number, 0);
//定义最大价值
int solution_value = 0;
//定义迭代元素i
int i = 0;
//由于一个都不拿肯定不是最优解,故无需操作当前向量,直接开始递归
BackpackProblem(taken_items, i, capacity, weights, values, solution, &solution_value);
//输出最优结果
PrintResult(solution, solution_value);
return 0;
}
/*
输入
10 6
1 8 4 3 5 2
1 2 3 4 5 6
*/
示例结果:
最后
以上就是轻松冰棍为你收集整理的【c++回顾】3.1经典算法问题-0/1背包价值最大问题的全部内容,希望文章能够帮你解决【c++回顾】3.1经典算法问题-0/1背包价值最大问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复