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

    四、求最优方案

    在转移的时候记录方案

  • 相关阅读:
    Windbg Call Stack(调用堆栈)窗口的使用
    设置微软符号服务器的又一方法
    windbg是如何搜索符号文件的?
    如何关闭/禁用.NET JIT调试对话框
    EXCEPTION_HIJACK(0xe0434f4e)异常的抛出过程
    异常EXCEPTION_HIJACK(0xe0434f4e)
    Windows WoW64浅析
    在执行一行代码之前CLR做的68件事
    异常CLRDBG_NOTIFICATION_EXCEPTION_CODE( 0x04242420)的抛出过程
    异常CLRDBG_NOTIFICATION_EXCEPTION_CODE( 0x04242420)
  • 原文地址:https://www.cnblogs.com/little-uu/p/14942394.html
Copyright © 2011-2022 走看看