• 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;i<n;i++) {
    			if(m[i][w]==m[i+1][w]) {
    				x[i]=0;
    			}
    			
    			else {
    				x[i]=1;
    				w-=array_w[i];
    			}
    			x[n]=(m[n][w]>0)?1:0;
    		}
    		
    	}
    }
  • 相关阅读:
    【OpenJudge 2.5-1792】这绝壁是一道玄学题!【DFS】
    【BZOJ1034】省队选手不务正业打泡泡堂(我也不知道是啥算法)
    文件操作的常用方法和使用
    数据类型所有方法和使用整理之------字典
    数据类型所有方法和使用整理之------列表
    用类的内置方法实现类型检查
    类的内置方法及描述符
    用python实现MRO算法
    RHEL6.5 DHCP服务器搭建
    Python之禅 吾心笃定
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309680.html
Copyright © 2020-2023  润新知