0-1背包问题

来源:互联网 发布:淘宝物流管理怎么设置 编辑:程序博客网 时间:2024/06/08 15:25

问题描述

  • 有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.两个不相交的连续子数组和的最大值
原创粉丝点击