前两天在华为笔试题的时候遇到了这个问题,做完之后发现自己有欠缺,回来赶紧复习一下
本文链接https://blog.youkuaiyun.com/qq_34175893/article/details/79832210
不说太多了,直接把代码贴出来,任何繁琐的理论都不如代码看着直接,我在代码中进行了详细的注释,保证只要看懂并理解了关键的几句代码及注释,0-1背包问题就变得很简单,原理什么的网上的博客很多,给大家分享几个比较好的参考链接
//#include "stdafx.h"
// stdafx.h中没有函数库,只是定义了一些环境参数,使得编译出来的程序能在32位的操作系统环境下运行。还有其他作用,自行参考百度百科
#include <iostream>
#include <string>
#include <vector>
using namespace::std;
/*
0-1 背包问题(迭代版)
输入:
products_count:商品的数量
capacity:背包的容量
weight_array:商品重量数组
value_array:商品价格数组
result:结果数组
输出:
result[products_count][capacity] : 最大价值
*/
void knapsack(int products_count, int capacity, vector<int>& weight_array, vector<int>& value_array, vector<vector<int>>& result)
{
for (int i = 1; i <= products_count; ++i)
{
for (int j = 1; j <= capacity; ++j)
{
if (weight_array[i] > j) // 当前背包的容量 j 放不下第 i 件商品时
{
result[i][j] = result[i - 1][j]; // 放弃第 i 件商品,拿第 i - 1 件商品
}
else
{
// 装入第 i - 1件商品,则容量变为j - weight_array[i]],价值加上value_array[i]
int value1 = result[i - 1][j - weight_array[i]] + value_array[i];
// 不装入第 i - 1 件商品 ,则此时容量i的价值和容量i-1的价值相同且装入的物品相同
int value2 = result[i - 1][j];
/**
* 问题的核心:状态转移方程, 选出两种选择(是否装入第i件物品)中价值较大的
*/
result[i][j] = value1 > value2 ? value1 : value2;
}
}
}
}
int main()
{
while (1)
{
/*
vector<int> a; //声明一个int型向量a
vector<int> a(10); //声明一个初始大小为10的向量
vector<int> a(10, 1); //声明一个初始大小为10且初始值都为1的向量
vector<int> b(a); //声明并用向量a初始化向量b
vector<int> b(a.begin(), a.begin() + 3); //将a向量中从第0个到第2个(共3个)作为向量b的初始值
//除此之外, 还可以直接使用数组来初始化向量:
int n[] = { 1, 2, 3, 4, 5 };
vector<int> a(n, n + 5); //将数组n的前5个元素作为向量a的初值
vector<int> a(&n[1], &n[4]); //将n[1] - n[4]范围内的元素作为向量a的初值
//全部输出
vector<int>::iterator t ;
for(t=a.begin(); t!=a.end(); t++)
cout<<*t<<" " ;
*/
int products_count, capacity;
vector<int> weight_array(1, 0); //声明一个初始大小为1且初始值都为0的向量 //大小和初值都是可选参数
vector<int> value_array(1, 0);
cout << endl << "-----------------------------" << endl;
cout << "please input products count and knapsack's capacity: " << endl; // 输入商品数量和背包容量
cin >> products_count >> capacity;
cout << "please input weight array for " << products_count << " products" << endl;
for (int i = 1; i <= products_count; ++i) // 循环输入每件商品的重量
{
int tmp;
cin >> tmp;
weight_array.push_back(tmp);
}
cout << "please input value array for " << products_count << " products" << endl;
for (int i = 1; i <= products_count; ++i) // 循环输入每件商品的价格
{
int tmp;
cin >> tmp;
value_array.push_back(tmp);
}
vector<vector<int>> result(products_count + 1, vector<int>(capacity + 1, 0)); // 结果数组 二维 (products_count+1)*(capacity+1)
knapsack(products_count, capacity, weight_array, value_array, result); // 调用动态规划算法
cout << "knapsack result is " << result[products_count][capacity] << endl;
// 调用动态规划算法之后,在result矩阵的r=products_count,c=capacity位置上的元素的值必是最大值
// 也就是说在任意一个products_count和capacity对应位置上的值都是当前情况下的最大价值
}
return 0;
}