背包问题
#include <iostream>
#include <vector>
using namespace std;
class BackPack{
public:
/* 背包1:
* 给定N个物品,重量分别为正整数
* 一个背包的最大承重为整数M
* 最多能带走多重的物品
* */
static int dpBackPack1(const vector<int> &arr, const int &weight){
if(arr.empty()) return -1;
vector<vector<bool>> dp(arr.size());
for(auto &it:dp){
it.resize(weight+1);
}
int maxWeight = 0;
for(int i = 0; i < arr.size(); ++i){
for(int w = 0; w < dp[i].size(); ++w){
//dp[i][w]表示能否用前i个物品拼成重量w
if(w == 0 || w == arr[i]){
dp[i][w] = true;
maxWeight = max(maxWeight, w);
continue;
}
dp[i][w] = false;
if(i > 0){
dp[i][w] = dp[i-1][w] || dp[i][w] ;
if(w >= arr[i]){
dp[i][w] = dp[i-1][w - arr[i]] || dp[i][w];
}
}
maxWeight = dp[i][w] ? max(maxWeight, w) : maxWeight;
}
}
return maxWeight;
}
/*有 n 个物品和一个大小为 m 的背包.
* 给定数组 A 表示每个物品的大小和数组 V 表示每个物品的价值.
* 问最多能装入背包的总价值是多大?
* 一个物品只能用一次
* */
static int dpBackPack2(const vector<int> &arr,
const vector<int> &value,
const int &target){
if(arr.empty()) return -1;
int n = (int)arr.size();
vector<vector<int>> dp(n);
for(auto &it:dp){
it.resize(target + 1);
}
int maxVal = -1;
for (int i = 0; i < dp.size(); ++i) {
for (int j = 0; j < dp[i].size(); ++j) {
//dp[i][j]表示用前i个物品拼出重量j的最大价值
if(j == 0){
dp[i][j] = 0;
continue;
}
dp[i][j] = -1;
if(i > 0){
dp[i][j] = max(dp[i][j], dp[i-1][j]);
if(j >= arr[i] && dp[i-1][j-arr[i]] != -1){
dp[i][j] = max(dp[i][j], dp[i-1][j-arr[i]] + value[i]);
}
}
maxVal = max(maxVal, dp[i][j]);
}
}
return maxVal;
}
static int dpBackPack3(const vector<int> &arr,
const vector<int> &value,
const int &target){
if(arr.empty() || value.empty()) return 0;
int n = (int)arr.size();
vector<vector<int>> dp(n);
for(auto &it:dp){
it.resize(target + 1);
}
int maxVal = -1;
for (int i = 0; i < dp.size(); ++i) {
for (int j = 0; j < dp[i].size(); ++j) {
//dp[i][j]表示用前i个物品拼出重量j的最大价值
if(j == 0){
dp[i][j] = 0;
continue;
}
dp[i][j] = -1;
if(i > 0){
dp[i][j] = max(dp[i][j], dp[i-1][j]);
}
if(j >= arr[i] && dp[i][j-arr[i]] != -1){
dp[i][j] = max(dp[i][j], dp[i][j-arr[i]] + value[i]);
}
maxVal = max(maxVal, dp[i][j]);
}
}
return maxVal;
}
/* 背包5:
* 给定N个物品,重量分别为正整数
* 一个正整数Target
* 问有多少种方法可以拼出Target
* 每个只能用1次
* */
static int dpBackPack5(const vector<int> &arr, const int &target){
if(arr.empty()) return -1;
int n = (int)arr.size();
vector<vector<int>> dp(n + 1);
for(auto &it:dp){
it.resize(target + 1);
}
dp[0][0] = 1;
for (int i = 1; i < dp.size(); ++i) {
for (int j = 0; j < dp[i].size(); ++j) {
//dp[i][j]表示用前i个物品拼出j有多少种方法
dp[i][j] = dp[i-1][j];
if(j >= arr[i-1]){
dp[i][j] += dp[i-1][j-arr[i-1]];
}
}
}
return dp[n][target];
}
/* 背包6:
* 给定N个物品,重量分别为正整数
* 一个正整数Target
* 问有多少种方法可以拼出Target
* 每个可以用多次
* */
static int dpBackPack6(const vector<int> &arr, const int &target) {
if (arr.empty()) return -1;
int n = (int) arr.size();
vector<int> dp(target+1);
dp[0] = 1;
for(int i = 0; i < n; ++i){
for(int j = 0; j < dp.size(); ++j){
if(j >= arr[i]){
dp[j] += dp[j - arr[i]];
}
}
}
return dp[target];
}
};
int main() {
vector<int > arr = {2, 3, 5, 7};
int weight = 11;
//10 2 3 5
cout<<BackPack::dpBackPack1(arr, weight)<<endl;
arr = {1, 2, 3, 3, 7};
int target = 7;
cout<<BackPack::dpBackPack5(arr, target)<<endl;
arr = {2, 3, 6, 7};
target = 7;
cout<<BackPack::dpBackPack6(arr, target)<<endl;
arr = {2, 3, 5, 7};
target = 10;
vector<int> value = {1, 5, 2, 4};
cout<<BackPack::dpBackPack2(arr, value, target)<<endl;
arr = {1};
target = 10;
value = {1};
cout<<BackPack::dpBackPack3(arr, value, target)<<endl;
return 0;
}
主要是给自己看的,所以肯定会出现很多错误哈哈哈哈哈
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律