揹包问题

package 揹包问题之多重揹包;
/*
 * 有编号分别为a,b,c的三件物品,它们的重量分别是1,2,2,它们的价值分别是6,10,20,
 * 他们的数目分别是10,5,2,
 * 现在给你个承重为 8 的揹包,如何让揹包里装入的物品具有最大的价值总和
 */
public class DongtaiGuihua {
	public static void main(String[] args) {
		int[] weight = {1,2,2};
        int[] value = {6,10,20};
        int[] num = {10,5,2};
        int[][] f = getMaxValue(weight,value,num,8,3);
        System.out.println();
        System.out.println("======================");

	}
	public static int[][] getMaxValue(int[] weight, int[] value,int[] num,int maxWeight,int n){
		int[][] f = new int[n][maxWeight+1];
		for(int i=0;i<n;i++){
			f[i][0] = 0; //列为0的什么都装不了
		}
		//初始化第一行 代表着最大装多少
		for(int j=1;j<=maxWeight;j++){
			int count = Math.min(num[0], j/weight[0]);
			f[0][j] = (j<weight[0])?0:count*value[0];
		}
		
		for(int i=1;i<n;i++){
			for(int j=1;j<=maxWeight;j++){
				if(j>=weight[i]){
					//这里有差距
					int count = Math.min(num[i], j/weight[i]);
					f[i][j] = f[i-1][j];
					for(int k=1;k<=count;k++){
						int temp = f[i-1][j-weight[i]*k] + k*value[i];
						if(temp >= f[i][j]){
							f[i][j] = temp;
						}
					}
				}
				else{
					f[i][j] = f[i-1][j];
				}
			}
		}
		
	    for(int i=0;i<n;i++)
	    {
	        for(int j=0;j<=maxWeight;j++)
	           System.out.print(f[i][j]+" ");  
	        System.out.println();
	    }
	    //判断路径
	    int[] path = new int[n];
	    int k = n-1;
	    int j=maxWeight;
	    while(k>0){
	    	int count = Math.min(num[k], j/weight[k]);
	    	if(j-weight[k]<0){
	    		
	    	}
	    	else {
	    		//这里不同
	    		for(int jishu=count;jishu>0;jishu--)
	            {
	                if(f[k][j] == (f[k-1][j-weight[k]*jishu]+jishu*value[k]))
	                {
	                    path[k] = jishu;
	                    j = j - jishu*weight[k];
	                    break;
	                }
	            }
	    	}
	    	k--;
	    }
	    //
	    path[0] = f[0][j]/value[0];

	    for(int i = 0; i < n; i++)
            System.out.print(path[i]+" ");
		return f;
	}
}
package 揹包问题之重量价值承重是否选择;
//二维数组 https://blog.csdn.net/na_beginning/article/details/62884939
public class DongTaiGuiHua {
	public static void main(String[] args) {
		int[] weight = {2,1,3,2};
        int[] value = {12,10,20,15};
        int[][] f = getMaxValue(weight,value,8,4);
        System.out.println("======================");
        int[] weight1 = {2,2,6,5,4};
        int[] value1 = {6,3,5,4,6};
        int[][] f1 = getMaxValue(weight1,value1,10,5);
	}
	//n件物品 0~n-1
	public static int[][] getMaxValue(int[] weight, int[] value,int maxWeight,int n){
		int[][] f = new int[n][maxWeight+1];
		for(int i=0;i<n;i++){
			f[i][0] = 0; //列为0的什么都装不了
		}
		//初始化第一行
		for(int j=1;j<=maxWeight;j++){
			f[0][j] = (j<weight[0])?0:value[0];
		}
		
		for(int i=1;i<n;i++){
			for(int j=1;j<=maxWeight;j++){
				if(j>=weight[i]){
					f[i][j] = (f[i-1][j]>(value[i]+f[i-1][j-weight[i]]))?f[i-1][j]:(value[i]+f[i-1][j-weight[i]]);
				}
				else{
					f[i][j] = f[i-1][j];
				}
			}
		}
		
	    for(int i = 0; i < n; i++)
	    {
	        for(int j=0;j<=maxWeight;j++)
	           System.out.print(f[i][j]+" ");  
	        System.out.println();
	    }
	    //判断路径
	    int[] path = new int[n];
	    int k = n-1;
	    int j=maxWeight;
	    while(k>0){
	    	if(j-weight[k]<0){
	    		
	    	}
	    	else if(f[k][j] == (f[k-1][j-weight[k]]+value[k])){
	    		path[k] = 1;
	    		j = j - weight[k];
	    	}
	    	k--;
	    }
	    if(f[0][j]>0)
	    {
	        path[0] = 1;
	    }
	    for(int i = 0; i < n; i++)
            System.out.print(path[i]+" ");
		return f;
	}
}
package 完全揹包问题之重量价值数量无限;

public class DongtaiGuihua {
	public static void main(String[] args) {
		int[] weight = {2,3,4,7};
        int[] value = {1,3,5,9};
        int[][] f = getMaxValue(weight,value,10,4);
        System.out.println();
        System.out.println("======================");

	}
	//n件物品 0~n-1
	public static int[][] getMaxValue(int[] weight, int[] value,int maxWeight,int n){
		int[][] f = new int[n][maxWeight+1];
		for(int i=0;i<n;i++){
			f[i][0] = 0; //列为0的什么都装不了
		}
		//初始化第一行 代表着最大装多少
		for(int j=1;j<=maxWeight;j++){
			f[0][j] = (j<weight[0])?0:(j/weight[0])*value[0];
		}
		
		for(int i=1;i<n;i++){
			for(int j=1;j<=maxWeight;j++){
				if(j>=weight[i]){
					//这里与0 1 揹包有差距
					f[i][j] = (f[i-1][j]>(value[i]+f[i][j-weight[i]]))?f[i-1][j]:(value[i]+f[i][j-weight[i]]);
				}
				else{
					f[i][j] = f[i-1][j];
				}
			}
		}
		
	    for(int i = 0; i < n; i++)
	    {
	        for(int j=0;j<=maxWeight;j++)
	           System.out.print(f[i][j]+" ");  
	        System.out.println();
	    }
	    //判断路径
	    int[] path = new int[n];
	    int k = n-1;
	    int j=maxWeight;
	    while(k>0){
	    	if(j-weight[k]<0){
	    		
	    	}
	    	else if(f[k][j] == (f[k][j-weight[k]]+value[k])){
	    		//这里不同
	    		path[k]++;
	    		j = j - weight[k];
	    	}
	    	k--;
	    }
	    //
	    path[0] = f[0][j]/value[0];

	    for(int i = 0; i < n; i++)
            System.out.print(path[i]+" ");
		return f;
	}
}

 

点赞