0-1背包问题
递归+记忆中间结果
#include <iostream>
#include "string"
#include<vector>
using namespace std;
int backage01(vector<int> w, vector<int> v, int contains, int index);
vector<vector<int>> memory;
int backage01(vector<int> w, vector<int> v, int contains) {
assert(w.size() == v.size());
if (w.size() == 0) return 0;
memory = vector<vector<int>> (v.size(), vector<int> (contains+1, -1));
return backage01(w, v, contains, w.size()-1);
}
//状态:背包容量为index, 装入的价值最高
//状态转移 f(i, C) = f(i-1, C)
// f(i-1, C-w[i]) + v[i]
int backage01(vector<int> w, vector<int> v, int contains, int index) {
if (index < 0 || contains < 0) return 0;
if (memory[index][contains] != -1) return memory[index-1][contains];
int res = backage01(w, v, contains, index-1);
if (contains - w[index] >= 0) {
res = max(res, backage01(w, v, contains-w[index], index-1) + v[index]);
}
memory[index][contains] = res;
return res;
}
int main() {
int weights[] = {1, 2, 3};
vector<int> w(weights, weights + 3);
int values[] = {6, 10, 12};
vector<int> v(values, values + 3);
int contains = 5;
int res = backage01(w, v, contains);
cout << res << endl;
}
动态规划(一)
时间复杂度(O(n * C))
空间复杂度(O(n * C))
#include <iostream>
#include "string"
#include<vector>
using namespace std;
//状态:背包容量为index, 装入的价值最高
//状态转移 f(i, C) = f(i-1, C)
// f(i-1, C-w[i]) + v[i]
int backage01(vector<int> w, vector<int> v, int contains) {
assert(w.size() == v.size());
if (w.size() == 0) return 0;
int n = w.size();
vector<vector<int>> memory(n, vector<int>(contains+1, 0));
for (int i = 0; i <= contains; i++) {
if (i >= w[0]) memory[0][i] = v[0];
else memory[0][i] = 0;
}
//打印中间结果
for (int i = 1; i < n; i++) {
for (int j = 1; j <= contains; j++) {
int res = memory[i-1][j];
if (j >= w[i]) {
res = max(res, memory[i-1][j-w[i]] + v[i]);
}
memory[i][j] = res;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j <= contains; j++) {
cout << memory[i][j] << " ";
}
cout << endl;
}
return memory[n-1][contains];
}
int main() {
int weights[] = {1, 2, 3};
vector<int> w(weights, weights + 3);
int values[] = {6, 10, 12};
vector<int> v(values, values + 3);
int contains = 5;
int res = backage01(w, v, contains);
cout << res << endl;
}
动态规划(二)
时间复杂度(O(n * C))
空间复杂度(O(2 * C))
#include <iostream>
#include "string"
#include<vector>
using namespace std;
//状态:背包容量为index, 装入的价值最高
//状态转移 f(i, C) = f(i-1, C)
// f(i-1, C-w[i]) + v[i]
int backage01(vector<int> w, vector<int> v, int contains) {
assert(w.size() == v.size());
if (w.size() == 0) return 0;
int n = w.size();
vector<vector<int>> memory(2, vector<int>(contains+1, 0));
for (int i = 0; i <= contains; i++) {
if (i >= w[0]) memory[0][i] = v[0];
else memory[0][i] = 0;
}
for (int i = 1; i < n; i++) {
for (int j = 1; j <= contains; j++) {
int res = memory[(i-1)%2][j];
if (j >= w[i]) {
res = max(res, memory[(i-1)%2][j-w[i]] + v[i]);
}
memory[i%2][j] = res;
}
}
//打印中间结果
for (int i = 0; i < 2; i++) {
for (int j = 0; j <= contains; j++) {
cout << memory[i][j] << " ";
}
cout << endl;
}
return memory[(n-1)%2][contains];
}
int main() {
int weights[] = {1, 2, 3};
vector<int> w(weights, weights + 3);
int values[] = {6, 10, 17};
vector<int> v(values, values + 3);
int contains = 5;
int res = backage01(w, v, contains);
cout << res << endl;
}
动态规划(二)
时间复杂度(O(n * C))
空间复杂度(O( C))
#include <iostream>
#include "string"
#include<vector>
using namespace std;
//状态:背包容量为index, 装入的价值最高
//状态转移 f(i, C) = f(i-1, C)
// f(i-1, C-w[i]) + v[i]
int backage01(vector<int> w, vector<int> v, int contains) {
assert(w.size() == v.size());
if (w.size() == 0) return 0;
int n = w.size();
vector<int> memory(contains+1, 0);
for (int i = 0; i <= contains; i++) {
if (i >= w[0]) memory[i] = v[0];
else memory[i] = 0;
}
for (int i = 1; i < n; i++) {
for (int j = contains; j >= w[i]; j--) {
int res = memory[j];
if (j >= w[i]) {
res = max(res, memory[j-w[i]] + v[i]);
}
memory[j] = res;
}
}
//打印中间结果
for (int j = 0; j <= contains; j++) {
cout << memory[j] << " ";
}
cout << endl;
return memory[contains];
}
int main() {
int weights[] = {1, 2, 3};
vector<int> w(weights, weights + 3);
int values[] = {6, 10, 17};
vector<int> v(values, values + 3);
int contains = 5;
int res = backage01(w, v, contains);
cout << res << endl;
}