现有n件物品和一个容量为c的背包。第i件物品的重量是重量为w[i],价值是v[i]。已知对于一件物品必须选择取(用1表示)或者不取(用0表示),且每件物品只能被取一次(这就是“0-1”的含义)。求放置哪些物品进背包,可使这些物品的重量总和不超过背包容量,且价值总和最大。
01背包问题:
c[i][j] = Max(c[i - 1][j], c[i - 1][j - weight[i]] + value[i]);
递归公式表示 当前的最优解 = Max(不放入当前的的物品,即c[i - 1][j] , 放入当前物品,则要预留出这个物品的 位置 即 c[i - 1][j - weight[i]] + value[i] )
然后递归得到所有的解。
每个物品只考虑放不放入一个,完全背包问题就考虑1~max个,多重就是考虑指定数量的物品,具体见代码。
// Study.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <string>
#include <algorithm>
#include <sstream>
#include <set>
#include <stack>
#define INT_MAX 2147483647 // maximum (signed) int value
#define INT_MIN (-2147483647 - 1) // minimum (signed) int value
;
using namespace std;
int Max(int a, int b)
{
return a > b ? a : b;
}
void baggage(int m, int n, vector<int> &weight, vector<int> &value)
{
vector<vector<int>> c(n + 1, vector<int>(m + 1, 0));
vector<int> t(m + 1, 0);
//01背包问题
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= 1; j--)
{
if (weight[i] <= j)
{
c[i][j] = Max(c[i - 1][j], c[i - 1][j - weight[i]] + value[i]);
}
else
c[i][j] = c[i - 1][j];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cout << c[i][j] << " ";
}
cout << endl;
}
//*******************************完全背包问题*************
cout << endl << "完全背包 " << endl;
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= 1; j--)
{
for (int k = 1; k <= j / weight[i]; k++)
c[i][j] = Max(c[i - 1][j], c[i - 1][j - k * weight[i]] + k * value[i]);
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cout << c[i][j] << " ";
}
cout << endl;
}
//*********多重背包问题***********
vector<int> num = { 0,1,1,1 };
cout << endl << "多重背包 " << endl;
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= 1; j--)
{
for (int k = 1; k <= j / weight[i] && k <= num[i]; k++)
c[i][j] = Max(c[i - 1][j], c[i - 1][j - k * weight[i]] + k * value[i]);
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cout << c[i][j] << " ";
}
cout << endl;
}
/*
//用一位数组节省空间
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= 1; j--)
{
if (weight[i] <= j)
{
t[j] = Max(t[j], t[j - weight[i]] + value[i]);
}
else
t[j] = t[j];
}
}
for (int j = 1; j <= m; j++)
{
cout << t[j] << " ";
}
cout << endl;
*/
}
int main()
{
int M, N;
//cin >> M >> N;
//vector<int> weight(N+1, 0);
//vector<int> value(N+1, 0);
//for (int i = 1; i <= N; i++)
//{
// cin >> weight[i] >> value[i];
//}
M = 10, N = 3;
vector<int> weight = { 0,3,4,5 };
vector<int> value = { 0,4,5,6 };
baggage(M, N, weight, value);
system("pause");
return 0;
}