当前位置: 首页 > news >正文

【算法刨析】完全背包

完全背包与01背包的区别

01背包对于一个物品只能选择一次,但是完全背包可以选择任意次; 

思路

和01背包类似,01背包我们只需要判断选或不选,完全背包也是如此,不同的是,对于这个物品我们在判断选后在增加一次选择的机会,直到不选,跳转至下一个物品即可;

一般代码:

 f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);

第k次,不选的话就是它本身,选的话就是直接选择k次即可;

当然这个代码在数据稍微大一点的时候就会超出时间限制;

#include<iostream>
using namespace std;
const int N=1004;
int f[N][N];
int w[N],v[N];int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++){cin>>v[i]>>w[i];}for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){for(int k=0;k*v[i]<=j;k++){f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);}}}cout<<f[n][m]<<endl;
}

优化思路

上面代码会超出时间限制是因为三层循环,下面我们来把第三层循环优化掉:

f[i][j]=max(f[i][j],f[i-1][j-v]+w,f[i-1][j-2*v]+2*w,f[i-1][j-3*v]+3*w......f[i-1][j-k*v]+k*w)

f[i][j-v]=max(             f[i][j-v],f[i-1][j-2*v]+w,f[i-1][j-3*v]+2*w......f[i-1][j-k*v]+k*w)

f[i-1][j-v]+w,f[i-1][j-2*v]+2*w,f[i-1][j-3*v]+3*w......f[i-1][j-k*v]+k*w 不就是f[i][j-v]+w

那么我们可以得到:f[i][j]=max(f[i][j],f[i-1][j-v]+w)

这样我们不就可以不用写第三层循环了吗?

直接用:

            f[i][j]=f[i-1][j];
            if(j>=v[i])
            f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);

优化代码:

#include<iostream>
using namespace std;
const int N=1004;
int f[N][N];
int w[N],v[N];int main()
{int n,m;cin>>n>>m;for(int i=1;i<=n;i++){cin>>v[i]>>w[i];}for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){f[i][j]=f[i-1][j];if(j>=v[i])f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);}}cout<<f[n][m]<<endl;
}

我们来看一下核心代码:

            f[i][j]=f[i-1][j];
            if(j>=v[i])
            f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);

还记得01背包的代码吗?
             f[i][j] = f[i - 1][j];

             if(j>=v[i])
             f[i][j]= max( f[i - 1][j],f[i - 1][j - v[i]] + w[i] );

是不是只有(红色标记):

  f[i][j]= max( f[i - 1][j],f[i - 1][j - v[i]] + w[i] );不同

再次优化代码:

注意:

这里我的j的大小是从小到大开始的:

01背包中,f[i][j]= max( f[i - 1][j],f[i - 1][j - v[i]] + w[i] );对于f[j]就相当于f[i-1][j]的大小,如果从小到大遍历,那么f[i-1][j]的大小就会发现变化,那么优化后的代码就不满足我们所推导的公式,所以我们要从大到小;

类比于01背包,完全背包的公式, f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i]);对于这个公式如果从大到小就会改变f[i][j]的大小,不满足所推导的公式;

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e4;
int f[N];
int w[N],v[N];int main()
{int n,m;cin>>n>>m;for(int i=0;i<n;i++)cin>>v[i]>>w[i];for(int i=0;i<n;i++){for(int j=v[i];j<=m;j++){f[j]=max(f[j],f[j-v[i]]+w[i]);}}cout<<f[m]<<endl;
}

以上就是全部内容!!

http://www.lryc.cn/news/347935.html

相关文章:

  • notepad++
  • Python ValueError: bad transparency mask
  • Linux本地部署Nightingale夜莺监控并实现远程访问提高运维效率
  • 开关电源功率测试方法:输入、输出功率测试步骤
  • QT 文字转语言插件
  • Kubernetes(k8s)的认证(Authentication)策略解析
  • Scikit-Learn决策树
  • Python面试题【python基础部分1-50】
  • 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段
  • 第Ⅷ章-Ⅱ 组合式API使用
  • stable-diffusion-webui配置
  • 1+X电子商务数据采集渠道及工具选择(二)||电商数据采集API接口
  • apinto OpenAPI
  • XYCTF - web
  • 学习方法的重要性
  • 把现有的 Jenkins 容器推送到一个新的镜像标签,并且重新启动新的容器
  • 难以重现的 Bug如何处理
  • 我与足球的故事 | 10年的热爱 | 伤病 | 悔恨 | 放弃 or 继续 | 小学生的碎碎念罢了
  • js图片回显的方法
  • Java中的maven的安装和配置
  • 轴承制造企业“数智化”突破口
  • UIButton案例之添加动画
  • C#链接数据库、操作sql、选择串口
  • 本地搭建各大直播平台录屏服务结合内网穿透工具实现远程管理录屏任务
  • macos使用yarn创建vite时出现Usage Error: The nearest package directory问题
  • 【JAVA入门】Day04 - 方法
  • 前端报错 SyntaxError: Unexpected number in JSON at position xxxx at JSON.parse
  • Mybatis进阶详细用法
  • Android 系统省电软件分析
  • 了解什么是Docker