0-1背包问题

问题描述

  • 有n个物品,第i个物品价值为vi,重量为wi,其中vi和wi均为非负数,背包的容量为W,W为非负数。现需要考虑如何选择装入背包的物品,使装入背包的物品总价值最大。

问题分析

  • 在选择装入背包的物品时,对每种物品i只有两种选择,装入或者不装入。
  • 假设前i种物品放入容量为j的背包中的最优值为m[i][j],则
    m[i][j] = max{m[i-1][j-wi]+vi, m[i-1][j]}, 当 j>= wi
    m[i][j] = m[i-1][j], 当 j< wi

实现如下

public class ZeroOneBag {

    public static void zeroOneBagMax(int[] v, int[] w, int c, int n)
    {
        int[][] m = new int[n][c+1];
        for(int i = 0; i < n; i++)
            m[i][0] = 0;
        for(int i = 0; i <= c; i++)
        {
            if(i < w[0])
                m[0][i] = 0;
            else
                m[0][i] = v[0];
        }
        for(int i = 1; i < n; i++)
        {
            int jMax = Math.min(c, w[i]-1);
            for(int j = 0; j <= jMax; j++){
                m[i][j] = m[i-1][j];
            }
            for(int j = w[i]; j <= c; j++){
                m[i][j] = Math.max(m[i-1][j-w[i]] +v[i], m[i-1][j]);
            }
        }
        System.out.println(m[n-1][c]);
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] v = new int[]{6,3,5,4,6};//{0, 60, 100, 120};
        int[] w = new int[]{2,2,6,5,4};//{0, 10, 20, 30};
        int c = 10;
        zeroOneBagMax(v, w, c,w.length);
    }
}

总结

  • 与0-1背包问题类似的问题有:1.子数组和接近某个值的问题,因为该值可以作为0-1背包中的容量c。2.将数组分成和最为接近的两个子数组。其实本质就是求一个子数组,其和最接近sum/2。
    关于子数组方面的拓展
  • 1.最大子数组问题
  • 2.零子数组问题
  • 3.两个不相交的连续子数组和的最大值
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值