完全背包 初学篇「建议收藏」

完全背包 初学篇「建议收藏」完全背包 初学

大家好,又见面了,我是你们的朋友全栈君。

关于更多背包的内容可以在我的“背包”类别中查看

一、题目

有 n 种物品和一个容量为 m 的背包,每种物品都有无限件可用。放入第 i 种物品的费用是
v i ,价值是 W i 。求解:将哪些物品装入背包,可使这些物品的耗费的费用总和不超过背包
容量,且价值总和最大。

二、基本思路

完全背包和01背包的不同之处就是在于,01背包每个物品只有一件,而完全背包每个物品有无限件。我们还是以二维数组来进行思考,我们在01背包中每次更新值时面临的决策是要不要放第i件物品,而在完全背包,我们需要抉择的便是,我们此时要放第i件物品几件?(0——最多能放的件数)

状态转移方程:F[i,j]=max{F[i-1,j],F[i-1,j-k*wi]+k*vi}

总的复杂度可以认为是 O(mn ni=0m/vi ) 这个复杂度是非常大的,我们还要改进这个复杂度。

三、简单的优化

若两件物品 i , j 满足 v i ≤ v j且 w i ≥ w j ,则将可以将物品 j 直接去掉,不用考虑。这个优化方式并不能满足最坏的情况,或许部分题目可以用这个优化卡过时间,故在此处并不做过多描述。

四、更好的优化

考虑到第 i 种物品最多选 m/v i 件,于是可以把第 i 种物品转化为 m /v i 件费用及价值均不变的物品,然后求解这个 01 背包问题。而这样不并不能优化太多的复杂度。
这时我们可以通过二进制的思想再次进行优化,通过几件相同的物品捆绑在一起,再相加我们可以得到每一个值(比如,此时我们第一件物品(就叫他a)我们最多可以放5件,那么我们把几个a捆绑一下,第一份就一个a,第二份两个a,第三份四个a。我们就可以发现这几份之间互相组合是一定可以完成1-5件a放入背包的情况的遍历的)这样一来就把每种物品拆成 O(log ⌊V /C i ⌋) 件物品,是一个很大的改进。
当然这依然不是最好的优化,我们依然不采用。

五、O(V N ) 的算法

还是以01背包的方向入手,01背包我们最终优化到的方法是使用一维数组,我们在进行遍历的时候是从后往前遍历的,为什么?我们比较的是还没装入此物品的状态,所以说,从后往前可以防止数据变化,而这个时候我们不就需要让数据变化起来吗,我们需要的就是已经选入第i件物品的子结果,(比如我们比较的是是不是要放两个第一件物品,我们要比较的是什么?是放入一件第一件物品的价值和放两件第一件物品的价值)所以这个时候我们只需要把第二个循环从前往后遍历就可以了。

CODE:

#include<cstdio>
#include<algorithm>
using namespace std;
int w[300],c[300],f[300010];
int V,n;
int main()
{
    scanf("%d%d",&V,&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%d%d",&w[i],&c[i]);
    }
    for(int i=1; i<=n; i++)
        for(int j=w[i]; j<=V; j++)//注意此处,与0-1背包不同,这里为顺序,0-1背包为逆序
            f[j]=max(f[j],f[j-w[i]]+c[i]);
    printf("max=%d\n",f[V]);
    return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/150680.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 面试官,不要再问我三次握手和四次挥手「建议收藏」

    面试官,不要再问我三次握手和四次挥手「建议收藏」三次握手和四次挥手是各个公司常见的考点,也具有一定的水平区分度,也被一些面试官作为热身题。很多小伙伴说这个问题刚开始回答的挺好,但是后面越回答越冒冷汗,最后就歇菜了。见过比较典型的面试场景是这样的:面试官:请介绍下三次握手求职者:第一次握手就是客户端给服务器端发送一个报文,第二次就是服务器收到报文之后,会应答一个报文给客户端,第三次握手就是客户端收到报文后再给服务器发送一个报文,三次握手就…

    2022年4月29日
    45
  • 计算机病毒模块测试题,计算机病毒分类测试题集

    计算机病毒模块测试题,计算机病毒分类测试题集以下有关计算机病毒分类的陈述______是正确的.A)病毒分为十二类B)病毒分为操作系统类型和文件类型C)没有分类D)病毒分为外壳型和侵入型根据计算机病毒的破坏能力,计算机病毒可分为A.良性病毒B.恶性病毒C.网络病毒D.引导病毒根据计算机病毒的存在方式进行分类,通常可以分为().A.复杂病毒B.引导病毒C.文件病毒D.网络病毒这个问题是一个选择题.请帮助给出正确的答案和分析,谢…

    2022年5月9日
    34
  • 缓冲区溢出攻击实践

    缓冲区溢出攻击实践缓冲区溢出攻击方法是黑客入门的基础,本文以一个具体的实例一步步介绍如何进行最初级的缓冲区溢出攻击。

    2022年7月12日
    10
  • VS2015 密钥_vs离线激活2015

    VS2015 密钥_vs离线激活2015企业版:HM6NR-QXX7C-DFW2Y-8B82K-WTYJV (一般我们都是安装的企业版)专业版:HMGNV-WCYXV-X7G9W-YCX63-B98R2

    2022年8月22日
    8
  • 最受欢迎的8个Python框架,满足你的各类需求「建议收藏」

    最受欢迎的8个Python框架,满足你的各类需求「建议收藏」今天给大家分享几个最受欢迎的Python框架。这些框架包括Web开发,高性能网络通信,测试,爬虫等等,如果你正在学习Python,那么应该可以满足你。1DjangoDjango应该是最出名的Python框架,是一款在数据库功能、后台功能、模板系统、网址匹配、缓存系统等方面有“先天”优势的开源框架。它可以通过几行简单的代码就让你的网站拥有一个强大的后台,轻松管理你的内容;强大,易扩展的模板系统,设计简易,代码,样式分开设计,更容易管理。小编整理的一整套系统的p-ython学习教程从最基础的

    2022年5月10日
    43
  • docker启动镜像容器命令_镜像删除

    docker启动镜像容器命令_镜像删除一、查看当前docker中下载的镜像,如下图,当前我的Docker容器中存在两个镜像,tomcat、mysql二、启动镜像(因启动命令参数过多,同时各种镜像启动时可以增加额外的参数,本次以启动mysql5.6为例)dockerrun-p本机映射端口:镜像映射端口-d–name启动镜像名称-e镜像启动参数镜像名称:镜像版本号参数释义:-p本机端口和容器启动端口映射-d后台运行–name容器名称-e镜像启动参数例:

    2022年9月22日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号