算法学习--01背包问题

有n个物品,它们有各自的体积和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和?
在这里插入图片描述

#include <algorithm>
#include <iostream>
#include <cstring> 
#include <string>
#include <vector>
#include <cmath>

typedef int* intp;
typedef int** intpp;
using namespace std;

intpp record;
int n;//物品数量
int bag_size;//背包容量
intp weight;//物品重量的数组
intp value;//物品价值的数组

//递归(index:物品编号, W:背包负重)
int dfs(int index, int W) {
	if (index == n || W <= 0) {
		return 0;
	}
	//不选当前物品
	int v2 = dfs(index + 1, W);
	//选择当前下标的物品
	if (W >= weight[index]) {
		int v1 = value[index] + dfs(index + 1, W - weight[index]);
		return max(v1, v2);
	}
	else {
		return v2;
	}
}

//优化递归(记录)
int dfs_2(int index, int W) {
	if (index == n || W <= 0) {
		return 0;
	}
	//计算前查找
	if (record[index][W] >= 0) {
		return record[index][W];
	}
	int res;
	//不选当前物品
	int v2 = dfs_2(index + 1, W);
	//选择当前下标的物品
	if (W >= weight[index]) {
		int v1 = value[index] + dfs_2(index + 1, W - weight[index]);
		res = max(v1, v2);
	}
	else {
		res = v2;
	}
	//返回前保存
	record[index][W] = res;
	return res;
}

//动规解法
int dp() {
	intpp arr_dp = new intp[n];
	for (int i = 0; i < n; i++) {
		arr_dp[i] = new int[bag_size + 1];
	}
	//初始化dp表的第一行
	for (int row = 0; row < bag_size + 1; row++) {
		if (row >= weight[0]) {
			arr_dp[0][row] = value[0];
		}
		else {
			arr_dp[0][row] = 0;
		}
	}
	//其他行
	for (int i = 1; i < n; i++) {
		for (int j = 0; j < bag_size + 1; j++){
			if (j >= weight[i]) {
				int v1 = value[i] + arr_dp[i - 1][j - weight[i]];//选择当前物品
				int v2 = arr_dp[i - 1][j];//不选当前物品
				arr_dp[i][j] = max(v1, v2);
			}
			else {
				arr_dp[i][j] = arr_dp[i - 1][j];
			}
		}
	}
	return arr_dp[n - 1][bag_size];
}

int main() {
	//输入
	cin >> n >> bag_size;
	weight = new int[n];
	value = new int[n];
	for (int i = 0; i < n; i++){
		cin >> weight[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> value[i];
	}
	record = new int* [n];
	for (int i = 0; i < n; i++) {
		record[i] = new int[bag_size + 1];
		memset(record[i], -1, (bag_size + 1) * sizeof(int));
	}
	cout << dfs(0, bag_size) << endl;
	cout << dfs_2(0, bag_size) << endl;
	cout << dp() << endl;
	return 0;
}

/*
测试用例:
4 5
2 1 3 2
3 2 4 2
*/
发布了25 篇原创文章 · 获赞 17 · 访问量 712

猜你喜欢

转载自blog.csdn.net/mu_mu_mu_mu_mu/article/details/104726025