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

    四、求最优方案

    在转移的时候记录方案

  • 相关阅读:
    docker 介绍,安装,镜像操作, docker换源
    go语言5 接口, 并发与并行, go协程, 信道, 缓冲信道, 异常处理, python进程线程
    [编织消息框架]目录
    2017总结
    赚钱方法[信息红利]
    面单 全单 单板 批发吉他民谣 知乎 百度知道 百度贴吧 吉他批发
    看第三部杀破狼感想
    海豚极货店 淘宝店开张啦
    我上头条了
    尤克里里 ukulele 单板 非kaka tom uma
  • 原文地址:https://www.cnblogs.com/little-uu/p/14942394.html
Copyright © 2011-2022 走看看