zoukankan      html  css  js  c++  java
  • 复习笔记之背包

    分类

    1. 01背包

    2. 完全背包

    3. 多重背包

    一、01背包

    解决问题:n个物品有价值和重量两个属性,容量为m的背包,每个物品只取一次,能取到的最大价值

    状态定义:dp[i][j]表示在前i个物品中选,容量为j,能取到的最大价值

    状态转移:dp[i][j] = max(dp[i-1][j],dp[i-1][j-w[i]]+c[i])这个物品取或者不取两种情况

    滚动数组优化:第一维只与i-1有关,倒序转移

    复杂度是(O(nm))

    例题:HDU Bone Collector luogu 采药 0629模拟赛T1也可以算01背包吧……

    其实还是想找一些高质量的例题吧,这些都太裸了,有时间再看看

    完全背包

    解决问题:n个物品有价值和重量两个属性,容量为m的背包,每个物品可以取无数次,能取到的最大价值

    状态定义:dp[i][j]表示在前i个物品中选,容量为j,能取到的最大价值

    状态转移:dp[i][j] = max(dp[i-1][j],dp[i][j-w[i]]+c[i]) 选或者不选

    滚动数组优化:需要覆盖,正序枚举

    复杂度是(O(nm))

    例题:luogu 疯狂的采药

    多重背包

    解决问题:n个物品有价值和重量两个属性,容量为m的背包,每个物品可以取有限次,能取到的最大价值

    二进制转化:因为一个数可以被拆分成多个2的k次幂相加,把一个物品拆成2的k次幂个物品,每个物品只能选一次,变成了01背包

    复杂度是(O(msumlimits_{i = 1}^n logk_i))

    代码:

    void change(int tmpw,int tmpc,int tmpk){
    	for (int i = 1;i <= tmpk;i <<= 1){
    		w[++cnt] = i*tmpw,c[cnt] = i*tmpc;
    		tmpk -= i;
    	}
    	if (tmpk) w[++cnt] = tmpw*tmpk,c[cnt] = tmpc*tmpk; 
    }
    

    例题:luogu 樱花

    其他背包

    一、恰好装满

    将dp[0,...,N][0]初始为0,其它dp值均初始化为-inf

    二、求方案总数

    将取max/min 换成求和,例如:

    dp[i][j] += dp[i-1][j]+dp[i-1][j-w[i]]+c[i]

    三、二维费用背包

    多开一维,其他和一维一样,比如01背包

    dp[i][j] = max(dp[i-w1[k]][j-w2[k]],dp[i][j])

    四、求最优方案

    在转移的时候记录方案

  • 相关阅读:
    会话执行存储过程,等待被阻塞,Kill session场景模拟
    会话断开数据保存情况
    Linux关闭透明大页配置
    ORA16019搭建DG设置归档线程参数报错
    如何将openssl、uuid和crypto的库文件放到本地指定库目录
    cscope中这样生成cscope.files
    使用kdesvn完成tags和branch功能
    ubuntu中设定ibus自启动
    使用kdesvn提交文件出现Aborting commit:'.lcd1602.ko.cmd' remains in conflict错误提示
    error: dereferencing pointer to incomplete type的解决办法
  • 原文地址:https://www.cnblogs.com/little-uu/p/14942394.html
Copyright © 2011-2022 走看看