背包问题
Posted oscar67
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包问题相关的知识,希望对你有一定的参考价值。
现有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; }
以上是关于背包问题的主要内容,如果未能解决你的问题,请参考以下文章