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

01背包问题 刷题笔记

思路 dp
用f[i][j]来表示当体积为j时 考虑前i件物品可以获得的 最大值 
记住f[i][j]本身是个价“价值” 
考虑两种状态 是否将第i件物品放入背包里面
将背包的体积从小到大递增来进行考虑
首先 考虑条件 如果当前增加的体积放不下下一件物品 
则该体积 可以获得的最大值可以直接继承上一个f[i-1][j] 
如果可以放下 则比较 放入与不放入谁获得的值较大
即 f[i-1][j]与f[i-1][j-v[i]]+w[i]比较
 //-v[i]是为了减去放入后的背包体积
 加w[i]是为了加上放入后获得的价值
 每一次存下的 都是基于考虑到当前物品 的最优选择
 比方说 前面已经进行了i件物品的选择 
 获得了一个基于i件物品的最大值
  这时候 第i+1件物品突然出现 体积为1,价值1000000;
  那么当背包体积只有1时的最大值会立刻被更新成100000;
  此时仍然是最优选择
  代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=1010;
int f[N][N];
int w[N],v[N];
int n,m;
int main(){
    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=1;j<=m;j++){
            if(j<v[i]){
            f[i][j]=f[i-1][j];
            }else{
                f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
            }
            
        }
    }
    cout<<f[n][m];
    return 0;
}

优化思路

二维到一维 

我们发现 考虑第i件物品时的最大值来自前面一层i-1件物品的最大值

也就是说 所有的当前层 都只来自上一层的最大值

而上上层已经不重要了

因此有没有可能直接删掉层数记录

观察发现f[i][]是从f[i-1][]这一层更新出来的

此时我们直接删除i

只使用j

观察式子f[j-v[i]]+w[i]

也就是说 如果我们逆序更新的话 需要使用和比较的数是j-v[i]

这个数是绝对小于j的 如果将j从m往0更新

保证了更新时只有大于等于j的数被覆盖掉了

而我们需要用的 j-v[i]则被保留下来

举例

如果我们逆序更新的话

假设 原来 f[j](1-5)是

1 2 5 7 9

然后我们逆序更新

for(int i=0;i<n;i++){
        for(int j=m;j>=v[i];j--){
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }

假设 此时j=5,v[i]=2,    f[j-v[i]]+w[i]=11那么

我们和上一个f[3]比较 比较完了以后将上一个f[5]覆盖掉

此时f[j](1-5)的情况为

1 2 5 7 11

然后当j=4;

v[i]=1;

f[j-v[i]]+w[i]=9;

即我们需要用的是f[3]

此时f[3]并没有被污染 

执行以后

f[j](1-5)的情况为

1 2 5 9 11

以此类推我们的目的达到了

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int w[N],v[N];
int j[N]; 
int n,m;
int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        //int x,y;
        cin>>v[i]>>w[i];
        //v[i]=x;
        //w[i]=y;
    }
    for(int i=0;i<n;i++){
        for(int j=m;j>=v[i];j--){
            f[j]=max(f[j],f[j-v[i]]+w[i]);
        }
    }
    cout<<f[m];
    return 0;

相关文章:

  • 排序算法:插入排序和希尔排序
  • 阿里云服务器怎么使用?3分钟搭建网站教程2024新版
  • 【设计模式】工厂模式与抽象工厂模式
  • SEO关键词策略:如何选取最适合你网站的关键词?
  • 一个简单的回调函数
  • IOS开发0基础入门UIkit-1cocoapod安装、更新和使用 , 安装中出现的错误及解决方案 M1或者M2安装cocoapods
  • javaSE-----继承和多态
  • 地平线零之曙光图文攻略,地平线零之曙光在MAC电脑能玩吗
  • vue2 element 实现表格点击详情,返回时保留查询参数
  • Windows Docker 部署 MySQL
  • 【Spring云原生】Spring Batch:海量数据高并发任务处理!数据处理纵享新丝滑!事务管理机制+并行处理+实例应用讲解
  • 基于JavaWEB SpringBoot婚纱影楼摄影预约网站设计和实现
  • 【打工日常】使用docker部署IT运维管理平台CAT
  • 微信小程序开发系列(十七)·事件传参·mark-自定义数据
  • 使用插件vue-seamless-scroll 完成内容持续动态
  • 「译」Node.js Streams 基础
  • ComponentOne 2017 V2版本正式发布
  • golang中接口赋值与方法集
  • Idea+maven+scala构建包并在spark on yarn 运行
  • iOS 系统授权开发
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 半理解系列--Promise的进化史
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 和 || 运算
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 基于组件的设计工作流与界面抽象
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 使用Swoole加速Laravel(正式环境中)
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 微信开放平台全网发布【失败】的几点排查方法
  • 我有几个粽子,和一个故事
  • 以太坊客户端Geth命令参数详解
  • PostgreSQL之连接数修改
  • ​用户画像从0到100的构建思路
  • #stm32驱动外设模块总结w5500模块
  • ()、[]、{}、(())、[[]]命令替换
  • (1)常见O(n^2)排序算法解析
  • (BFS)hdoj2377-Bus Pass
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (转)EXC_BREAKPOINT僵尸错误
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .NET Core中的去虚
  • .NET Micro Framework初体验(二)
  • .NET业务框架的构建
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • @Transactional类内部访问失效原因详解
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [ vulhub漏洞复现篇 ] Apache APISIX 默认密钥漏洞 CVE-2020-13945
  • [2669]2-2 Time类的定义
  • [AIGC] MySQL存储引擎详解
  • [AR Foundation] 人脸检测的流程
  • [BZOJ 4034][HAOI2015]T2 [树链剖分]