• 复习笔记之背包


    分类

    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])

    四、求最优方案

    在转移的时候记录方案

  • 相关阅读:
    为什么不能直接导入Statsmodels使用?
    数据分析工作的主要内容和基本流程
    Nodejs 包与 NPM 第三方模块安装和 package.json 以及 CNPM (4)
    CommonJs 和 Nodejs 中自定义模块 (3)
    pyhthon 处理pdf 合集
    02 nodejs HTTP模块和url模块配置supervisor
    1 nodejs简介与开发环境配置
    mysql 修改root密码和禁用无密码登录配置
    floodFill填充函数函数(六)
    粗略的调整图片对比度和亮度(五)
  • 原文地址:https://www.cnblogs.com/little-uu/p/14942394.html
Copyright © 2020-2023  润新知