Java 0-1背包问题

题目描述

给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,背包的容量为C。如何选择装入背包的物品,可以使得装入背包中物品的总价值最大?

输入

每组输入包括三行,
第一行包括物品个数n,以及背包容量C。
第二、三行包括两个一维数组,分别为每一种物品的价值和重量。

输出

输出包括两行,第一行为背包的最大总价值,第二行为所选取的物品。
例如:最大总价值=15,物品选取策略为11001。

样例输入 Copy

5 10
6 3 5 4 6
2 2 6 5 4

样例输出 Copy

15
11001

具体的注意事项注释有

import java.util.Scanner;

public class Zero_OneBag {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();//物品的个数
	    int w=sc.nextInt();//背包的容量
	    int array_v[]=new int[n+1];//价值数组
	    int array_w[]=new int[n+1];//重量数组
	    int x[]=new int[n+1];//记录数组
	    int m[][]=new int[n+1][w+1];//记录数组
	    for(int i=1;i<=n;i++) {
	    	array_v[i]=sc.nextInt();//从1开始记录
	    }
	    for(int i=1;i<=n;i++) {
	    	array_w[i]=sc.nextInt();//从1开始记录
	    }
	    int res=zero_onebag(array_v,array_w,w,m);
	    System.out.println(res);
	    traceback(m,array_w,w,x);
	    for(int i=1;i<=n;i++) {
	    System.out.print(x[i]);
	    }

	}

	private static int zero_onebag(int[] array_v, int[] array_w, int w, int[][] m) {
		int n=array_v.length-1;
		int max=Math.min(array_w[n]-1, w);
		/*
		 * 最后一行单独处理
		 */
		for(int i=0;i<=max;i++) {
			m[n][i]=0;
		}
		for(int i=array_w[n];i<=w;i++) {
			m[n][i]=array_v[n];
			//第n行不需要考虑放不放,只要放的下肯定要放,有总比没有好
		}
		/*
		 * 1到n-1处理
		 */
		for(int i=n-1;i>=1;i--) {
			max=Math.min(array_w[i]-1, w);
			for(int j=0;j<=max;j++) {
				m[i][j]=m[i+1][j];
			}
			for(int j=array_w[i];j<=w;j++) {
				m[i][j]=Math.max(m[i+1][j], m[i+1][j-array_w[i]]+array_v[i]);
				/*
				 * 就是来判断第n-1个物品值不值得放,如果放上以后,价值是 m[i+1][j-array_w[i]]+array_v[i];
				 * 但是有可能 m[i+1][j-array_w[i]]=0,因为可能容量不够,放不下第n个
				 */
			}	
			
		}
		
		return m[1][w];

	}
	public static void traceback(int m[][],int array_w[],int w,int x[]) {
		/*
		 * 构造路径,首先比较m[i][w]和m[i+1][w];
		 * 如果相同说明没放第i个,如果不同则说明放了
		 * 再将w减去放了的重量
		 */
		int n=array_w.length-1;
		for(int i=1;i0)?1:0;
		}
		
	}
}

你可能感兴趣的:(Algorithm)