2019年5月2日 背包问题的模板

    看了一上午背包,整理的成果

   背包问题

问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。

初始化

   如果要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1..V]均设为-∞

   如果要求价格尽量最大,初始化时应该将f[0..V]全部设为0  

1.0-1背包问题:最基本的背包问题,每个物品最多只能放一次。

    for i=1..n

    for v=V..0

    f[v]=max{f[v],f[v-w[i]]+c[i]};

 //01背包  

void ZeroOnePack(int c, int w)  

{for (int v = V; v >= c; v--)  

  {dp[v] = max(dp[v], dp[v - c] + w);}}  

2.完全背包问题:基本的背包问题模型,每种物品可以放无限多次。

   for i=1..N

   for v=0..V

   f[v]=max{f[v],f[v-weight]+cost}

  思路:将第i种物品拆成费用为w[i]*2^k、价值为c[i]*2^k的若干件物品,其中k满足w[i]*2^k<=V

//完全背包  

void CompletePack(int c, int w)  

{for (int v = c; v <= V; v++)  

  { dp[v] = max(dp[v], dp[v - c] + w);}}

3.多重背包问题:每种物品有一个固定的次数上限。 

  for(i=1;i<=N;i++)//N种物品

    for(j=V;j>=0;j--)//容量为V

        for(k=0;k<=num[i];k++)//每种物品最多有num[i]个

            if(j-k*w[i]>=0)//当前容量-k个物品的重量>=0

                f[j]=max(f[j],f[j-k*w[i]]+k*c[i]);

//多重背包  

void MultiplePack(int c, int w, int num)  

{ if (c * num >= V)  

  {CompletePack(c, w);}  

 else{  

   int k = 1;  

   while (k < num){  

     ZeroOnePack(k*c, k*w);  

     num -= k;  

     k <<= 1;}  

     ZeroOnePack(num*c, num*w);}}  

 4.混合三种背包问题:将前三种的问题叠加成较复杂的问题。

 【01背包与完全背包的混合】

for i=1..N

    if 第i件物品是01背包(只取一次时)

        for v=V..0

            f[v]=max{f[v],f[v-w[i]]+c[i]};

    else if 第i件物品是完全背包(可以取无限多时)

        for v=0..V

            f[v]=max{f[v],f[v-w[i]]+c[i]};

【加上多重背包】 

for i=1..N

    if 第i件物品是01背包(只取一次时)

        ZeroOnePack(c[i],w[i])

    else if 第i件物品是完全背包(可以取无限多时)

        CompletePack(c[i],w[i])

    else if 第i件物品是多重背包(有固定取的次数时)

        MultiplePack(c[i],w[i],n[i])

 5.二维费用的背包问题:费用增加了一维。

问题:对于每件物品,具有两种不同的体积,选择这件物品必须同时付出这两种代价,对于每种代价都有一个可付出的最大值(背包容量)。

for (int i=0; i<=V; i++) // 边界

      for (int j=0; j<=U; j++)

          s[i][j]=0; 

for (int i=1; i<=N; i++)

      for (int j=V; j>=v[i]; j--)

            for (int k=U; k>=u[i]; k--) 

                s[j][k]=max(s[j][k], s[j-v[i]][k-u[i]]+c[i]);

6. 分组的背包问题:对于每件物品,具有两种不同的费用;选择这件物品必须同时付出这两种代价。

 问题:有N件物品和一个容量为V的背包。第i件物品的体积w[i],价值是c[i]。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。

for 所有的组k

    for v=V..0

        for 所有的i属于组k

            f[v]=max{f[v],f[v-w[i]]+c[i]}

7.有依赖的背包问题:给物品的选取加上限制的方法。  

问题:背包问题的物品间存在某种“依赖”的关系,也就是说,i依赖于j,表示若选物品i,则必须选物品j。

 

 

下午比赛时一直不在状态,可能是刚吃饱饭,或者中午没休息,还是说自己就是心不在焉的,水了一下午,很对不起我的两位队友,我一定认真整理资料,明天调整好状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值