背包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}

}

原文地址:https://www.cnblogs.com/spiderKK/p/4355782.html