zoukankan      html  css  js  c++  java
  • 背包DP:背包九讲学习记录

    01背包:
    {
    v c[i] w[i]
    二维:

    f[i,j]=将前i个物品恰放于容量为v的背包中的最大价值
                      ~~~~~~
    不选第i个物品 f[i,j]:=f[i-1,j];
      选第i个物品 f[i,j]:=f[i-1,j-c[i]]+w[i];
    f[i,j]:=max{f[i-1,j],
                f[i-1,j-c[i]]+w[i]}


    一维:

    f[v]=恰放于容量为v的背包中的最大价值
    f[v]:=max{f[v],f[v-c[i]]+w[i]}

    for i:=1 to n do
        for j:=v downto 0 do
            f[j]:=max{f[j],f[j-c[i]]+w[i]}

    or

    for i:=1 to n do
        for j:=v downto 0 do
            f[i,j]:=max{f[i-1,j],f[i-1,j-c[i]]+w[i]}

    ————————————————
    misunderstanding:
    注意f[i][v]有意义当且仅当存在一个前i件物品的子集,
    其费用总和为v。所以按照这个方程递推完毕后,
    最终的答案并不一定是f[N] [V],
    而是f[N][0..V]的最大值。
    如果将状态的定义中的“恰”字去掉,
    在转移方程中就要再加入一项f[i][v-1],
    这样就可以保证f[N] [V]就是最后的答案。
    ————————————————

    }


    完全背包
    {

    有n种物品和一个容量为v的背包
    第i件物品的费用为c[i]
               价值为w[i]
    每件可取无数件

    f[i,j]=将前i个物品恰放于容量为v的背包中的最大价值
                      ~~~~~~          
    f[i,j]:=max{f[i-1,j-k*c[i]]+k*w[i]  | 0<=k*c[i]<=v}

    优化:
    1:如果物品i与物品j c[i]<c[j] and w[i]>w[j],就把j去掉
    2:转化为01背包
       由于第i件物品最多选v/c[i]件,那就把第i件物品转化为
       (v/c[i])件i物品
       基本思路:将一种物品拆成多种物品

    O(n*v)
    for i:=1 to n do
        for j:=0 to v do
            f[i,j]:=max{f[i-1,j],f[i-1,j-c[i]]+w[i]}

    or

    for i:=1 to n do
        for j:=0 to v do
            f[j]:=max{f[j],f[j-c[i]]+w[i]}

    misunderstanding:
    O(n*v)的算法原理没搞懂

    }


    多重背包
    {

    有n中物品和一个容量为v的背包,
    第i种物品费用为c[i]
             价值为w[i]
             最多选n[i]件

    第一个思路:
    对于第i个物品有(n[i]+1)个决策
        ......不选、选一件、选两件、... 、选n[i]件
    so,可得转移方程
        f[i,j]:=max{f[i-1,j-k*c[i]]+w[i]*k | 0<=k<=n[i]}
        复杂度 O(v*siga(n[i]))

    简单的第二个思路
    转化为01背包。把第i个物品转化为n[i] 件i物品
    然后就是一个01背包

    misunderstand:
    关于二进制以及单调队列的东西

    }

    混合背包
    {
    将以上三种背包混合,有的物品只能取一种,
    有的物品可取无限次,有的可取次数由一个上限


    感觉好像不算太难

    for i:=1 to n do
        begin 如果是01背包
                  for j:=v downto 0 do
                      f[i,j]:=max{f[i-1,j],f[i-1,j-c[i]]+w[i]};
              如果是完全背包
                  for j:=0 to v do
                      f[i,j]:=max{f[i-1,j],f[i-1,j-c[i]]+w[i]};
              如果是多重背包
                  for j:=v downto 0 do
                      begin for k:=0 to v/c[i] do
                                if f[i,j]<f[i-1,j-k*c[i]]+(w[i]*k)
                                   then f[i,j]:=f[i-1,j-k*c[i]]+(w[i]*k)
                      end;
        end;
    }

    二维费用的背包
    {
    问题:对于每种物品,有两个代价,
         如果选择这种物品,就要支付这两种代价

    a[i],b[i] 代价
    v[i]      利益
    f[i,j,k] 前i件物品支付j,k的代价之后得到的最大利益

    f[i,j,k]:=max{f[i-1,j,k],
                  f[i-1,j-a[i],k-a[i]]+v[i]}

    for i:=1 to n do
        for j:=v downto 0 do
            f[i,j,k]:=max{f[i-1,j,k],
                          f[i-1,j-a[i],k-a[i]]+v[i]}

    常以隐含条件出题

    01背包中限制选取数量
        //每个物品的b[i]=1//

    }

    **
    分组背包
    {
    有n件物品,和一个容量为v的背包
    划分为k组,每组的物品互相冲突{只选一件}

    f[i,j]{前i组物品花费代价为j所获得的最大利益}

    f[i,j]:=max{f[i-1,j],f[i-1,j-v[i][k]]  |  0<=k<=第i组物品的数量 }

    f[j]:=max{f[j],f[j-v[i][k]  |  0<=k<=第i组物品的数量 }

    for i:=1 to n do
        for j:=v downto 0 do
            for k:=1 to 第i组物品的数量
                 
    }

    ***
    有依赖的背包
    {
    题意:
    物品间存在依赖关系
    简化:
       1、不存在一件物品依赖多件物品
       2、不存在一件物品及依赖其他物品,有被别的物品锁依赖
    将不被其他物品所依赖的物品叫  主件
                依赖其他物品的叫  附件

    所有物品由{有一个主件和多个附件}集合组成

    假设有n个集合 {有c[i]个附件}
        选择方案:1、不选主件
                  2、只选主件
                  3、选主件和一个附件  {c[i]种}
                  4、选主件和两个附件  {}
                  5、选主件和三个附件  {}
                  .
                  .
                  .
                  .
                  .
                  c[i]+2、 选主件和c[i]个附件 {1种}
        总数是2^c[i]+1
       
    将一件物品扩展为2^c[i]+1件

    一个简单的优化:对于一个集合中代价相同的组合,只保留一个利益最大的

    }

    ***
    泛化背包
    {
    题意:
    在一个背包容量为v的背包问题中,泛化物品的v和w有一个严格的关系
    当分配给他的费用为w[i]时,利益为v[i]

    感觉它的意思是每一种背包问题都可以看作是一种泛化背包
    01背包,当代价是w[i]时,利益是v[i]; 其余的时候v[i]=0
    完全背包,当代价w=w[i]*k{0<=k<=V/w[i]} 利益是v[i]*k;
              其余的时候v[i]=0;
    多重背包,当代价w=w[i]*k{0<=k<=n[i]} 利益是v[i]*k
              其余的时候v[i]=0;

    当只有两件泛化物品时  q,p
           f[i]=q[i]+p[v-i];
           最大利益是 max{f[i]} {0<=i<=v}

    }

  • 相关阅读:
    Eclipse去掉js错误校验
    教学平台详细设计
    CentOS 6.3下部署LVS(NAT)+keepalived实现高性能高可用负载均衡
    通过CentOS克隆虚拟机后发现无法启动网卡或无法上网的解决办法
    使用U盘引导安装CentOS操作系统
    项目的热加载
    【转载】SQLServer全文搜索
    【转载】Lucence.Net
    【转载】Discuz!NT企业版之Sphinx全文搜索
    【转载】MySQL主从复制(MasterSlave)与读写分离(MySQLProxy)实践
  • 原文地址:https://www.cnblogs.com/spiderKK/p/4355782.html
Copyright © 2011-2022 走看看