题解 | #01背包#

01背包

https://www.nowcoder.com/practice/2820ea076d144b30806e72de5e5d4bbf

2022.0906算法第55题01背包
这道题也不容易想,但是竟然归为简单题,
我当时没想到需要和dp[i-1][j-vw[i-1][0]]离的那么远的值发生关系
1、状态矩阵建立了
2、初始值没弄ing错
3、状态转移方程没搞明白,已经把一个例子的状态矩阵写出来了
        但是没想明白dp[i][j]是怎么得到的,有几个方向过去的
解释:
dp[i][j]可以理解为物品i放置或者不放置,就这两种情况‘
当然这是有前提的,就是当前的物品i有这两种选择
下面就要分情况讨论了:
当物品i的体积大于背包的容量时,那肯定是没办法放的,也就是只能选择i-1个物品的最大值dp[i][j]=dp[i-1][j];
当物品i的体积小于等于背包的容量时,此时可以选择物品i是否放置,此时就有两种情况
1、物品i放置,则要考虑背包取出物品i体积的剩余空间,装入前i-1个物品的最大重量(注意此时物品i已经使用,不能在使用了,所以时i-1)
        ,这是将去除物品i的剩余体积对应的最大重量加上物品i的重量就是此时背包的重量
2、物品i不放置,不放置的结果和上面体积大于背包的容量时一样,都是选择i-1个物品的最大值dp[i][j];
        针对物品i的体积小于等于背包的容量的情况,取1和2的最大值就是物品0-i选取,容量为i的背包,的最大重量。
这次的理解应该算是比较准确的了,
int knapsack(int V, int n, vector<vector<int> >& vw) {
    //状态矩阵,表示从i个物品中选取,背包容量为j时的最大重量
    //明确状态矩阵的含义,下标的含义十分重要。。。
    //这里面就有初始化了。直接将左边界和上边界赋值为0,这就是初始化
    vector<vector<int>> dp(n+1,vector<int>(V+1));
    //循环计算状态矩阵中的每一个值
    for(int i=1;i<=n;i++){
        for(int j=1;j<=V;j++){
            //判断此时是否能选择物品i的条件
            //当背包容量小于等于物品i的体积时,表明此时可以选择物品i,
            //但是这时还是需要考虑是否选择物品i
            //1、物品i不放置,则此时dp[i][j]就等于前i-1个物品装入背包容量为j的最大重量也就是dp[i-1][j]
            //2、物品i放置,则需要考虑背包容量j去除物品i的体积,
            //    剩余的体积装入前i-1个物品的最大重量(注意此时物品i已经选择,只能从前i-1个物品中进行选择。
            //    此时的重量为前i-1个物品装入当前容量j去除物品i的体积剩余体积的最大重量dp[i-1][j-vw[i-1][0]]
            //    在加上物品i的重量
            //将1和2取最大值就是当前物品的最大值。
            if(vw[i-1][0]<=j){
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-vw[i-1][0]]+vw[i-1][1]);
            }
            //当vw[i-1][0]>j时,无法选择物品i,只能选择从前i-1个物品中选取
            //此时dp[i][j]就等于前i-1个物品装入背包容量为j的最大重量也就是dp[i-1][j]
            else{
                dp[i][j]=dp[i-1][j];
            }
        }
    }
    return dp[n][V];    
}


针对01背包,每个物品只能选择一次。
完全背包则有无数个物品,每个物品可以多次选择(这个问题可以尝试,需要对状态转移方程进行修改)
多重背包每个物品的数量各不相同
分组背包按组分开,每组选择一个。。。
#算法题#
全部评论
同感,简单题刷完了,这道是唯一剩下的。最主要原因是这是个二维表,求依据体积最大重量而不输出物品。
点赞 回复 分享
发布于 2024-09-05 00:35 四川

相关推荐

1、自我介绍2、Agent项目是实习项目还是个人项目?有没有上线?3、拷打实习(10min)4、大模型微调,你的训练数据集是如何构建的?数据量有多大?5、在构建数据集的过程中,遇到了哪些挑战?花了多长时间?6、你之前的实习经历偏后端工程,你未来的职业规划更倾向于纯后端开发,还是希望从事与AI/大模型结合的工作?7、详细讲一下Golang中Channel的概念和作用,它是否是并发安全的?8、Channel和传统的锁(Mutex)在实现并发控制时有什么区别?各自的适用场景是什么?9、讲一下GMP模型10、当P的本地队列为空或者不为空时,它会怎么去调度G(协程)?11、Redis支持哪些数据结构12、为什么Redis的速度这么快13、如何实现一个类似淘宝搜索框的实时商品名称模糊搜索功能?14、实时输入联想与输入完成后点击搜索在技术实现上有什么本质区别?15、实时搜索通常使用什么网络协议(如WebSocket)?你了解或有使用过吗?讲一下16、请详细说明微信扫码登录的完整流程和背后发生的原理17、在微服务架构中,服务发现和负载均衡是如何实现的?18、服务注册中心(如Nacos,&nbsp;Consul)是如何工作的?服务实例如何注册和保活(如通过心跳机制)?19、讲一下Agent中的“长短期记忆”20、什么样的信息应该放在长期记忆,什么样的信息放在短期记忆?21、当对话轮数很多,上下文窗口不足时,有哪些处理策略?(如截断、压缩)22、如果要进行记忆压缩,通常有哪些方法?23、了解过Agent的设计范式吗?有哪些?24、你设计的Agent是怎么实现ReAct模式的?详细讲讲25、手撕:实现一个并发任务处理器:给定一个包含100个任务ID的列表,要求控制最大并发数为3,模拟并发调用某个外部接口(如打印ID)26、反问
查看24道真题和解析
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务