今天要尽量把前段时间写的算法都总结一遍。。不过分析写太慢了。。所以大部分找天再补上(≡(▔﹏▔)≡以后我还记得是怎么一回事么。。。),以后再补上算法分析的时候顺便可以再重新把算法看一遍~~~

0-1背包问题,因为都能搜到题目是啥米意思,所以就大概说一下输入输出

输入如下:第一行为背包总数n,背包最大容量C,第二行为对应各背包的载重量,第三行为对应各背包的价值量。

3 6

4 3 2

5.0 4.0 1.0

输出:6.0

package com.java.struture;
import java.util.Scanner;
public class ZeroOne {
    public static double bag(int n ,int C , int[]w, double[]v){
        double [] Val = new double[2*n+1];
        //i为当前对应的背包
        for(int i = 0 ; i < n ;i++){
            //j为剩余背包容量
            for(int j = C; j >=0;j--){
                if(j>=w[i] && Val[j] < Val[j-w[i]]+v[i])
                    Val[j] = Val[j-w[i]]+v[i];
            }
        }
        return Val[C];
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int nums = sc.nextInt();//背包总数
        int C = sc.nextInt();//背包总容量
        int [] w = new int[nums];//每个背包的重量
        double [] v = new double[nums];//每个背包的价值
        for(int i = 0 ; i < nums ;i++){
            w[i] = sc.nextInt();
        }
        for(int i = 0 ; i < nums ;i++){
            v[i] = sc.nextDouble();
        }
        double maxval = bag(nums,C,w,v);
        System.out.println(maxval);
    }
}

如果剩余容量j>当前背包的容量w[i]这时候就考虑要不要把这个物品放上去了。

如果放进去后的价值量大于未放进去的价值量,那么就把它放进去,否则放弃。

上一句话是什么意思呢?我一开始在想的时候是带有疑问的,如果顺着放东西的思路来想的话,我现在背包剩余容量是6,我有一个重量是5的物品,这物品肯定是带有价值的,那放进去肯定会使得这个背包的价值量增大才对的,为什么还要通过判断决定是否放进去呢?

往反方向思考,这个背包容量是6,额,直接放图比较方便分析:

0-1背包算法——动态规划_java

其实就是放入一个物品w[i],那么背包的价值就是由这个物品的价值v[i]和剩下容量的价值Val[j-w[i]]组成的。而看图可以简单看出我们需要的就是从这个3个Val[6]中寻找最大的Val[6]返回(Val[6]表示剩余容量为6的背包的总价值量)。可以分析为放入物品1的话,价值量就由Val[2]+v[0]确定,而再一次循环的时候如果发现另外一个Val[6](放入另一个物品)比这个Val[6]大的话就替换这个Val[6],同理对所有剩余容量的背包都按这样的算法思路。如放入第一个物品后就寻找Val[2]最大的价值量,这样来使得Val[6]的价值量最大。