关于01背包的记忆化搜索

1.给定背包容量,物品数量

2.给定每个物品的体积和价值

分析:对于每个物品,只有选和不选两种选择,我们需要对每个物品都进行这两种选择(前提是可以装进背包)。那么我们就可以用搜索解法来解决,但是可能复杂度会很高,所以我采用记忆化搜索。

下面给出代码:

#include<iostream>
#include<cstring>
#include<stack>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
using namespace std;
int T, M;//分别是背包容量,物品个数
int a[105];//体积
int b[105];//价值
int f[105][1005];//i是遍历到第i个物体,j是当前已经装的物品体积
int ans = 0;
int dfs(int def, int sum) {//表示从第i层开始搜,此时背包中有sum,【还可以获得的最大价值】
  //【注意】上一行的获得的最大价值是【还可以获得的】,不是最大的

 if (f[def][sum]!=-1)return f[def][sum];价值
    if (def == M + 1) {
        return f[def+1][sum]=0;//搜到第M+1件物品,那从def+1层往后没有物品,自然价值就是0
    }
    int x = 0;
    if (a[def] + sum <= T) {
        x = dfs(def + 1, sum + a[def])+b[def];//够选我才能选
    }
    x = max(x, dfs(def + 1, sum));//不选和选比较一下
    return f[def][sum] = x;//取最大值
}
int main()
{
    memset(f, -1, sizeof(f));//这个初始化为-1,因为价值是0的话也合法
    cin >> T >> M;//背包容量,物品编号
    for (int i = 1; i <= M; i++)cin >> a[i] >> b[i];
    cout << dfs(1, 0) << endl;
    return 0;
}

题目是洛谷P1084;

本人是弱弱,有可能会写错,欢迎大佬来指点批评

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值