//日期:19.4.16
//作者:***
//功能:我的面试编程题目练习二十
//=====================================================
//问题描述:优化01背包的二维数组为一位数组的滚动使用
package com.*********;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;
public class Practice2 {
//主函数作为代码测试的入口
public static void main(String args[])
{
Practice2 pp = new Practice2();
pp.run();
}
//封装函数,客户端交互
public void run()
{
BufferedReader br=null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入背包的总容量:");
int weightSum = Integer.parseInt(br.readLine()); //得到控制台的输入信息背包容量
System.out.println("输入一共有多少个物品:");
int num = Integer.parseInt(br.readLine()); //得到控制台的输入信息物品数量
int [] weight_array = new int[num]; //构造保存物品重量的数组
int [] money_array = new int[num]; //构造保存物品价值的数组
for(int i=0; i<num; i++)
{
System.out.println("请输入第"+(i+1)+"个物品的重量和价值(空格隔开):");
String str = br.readLine();
String [] strc = str.split(" ");
weight_array[i] = Integer.parseInt(strc[0]); //得到用户输入的物品重量
money_array[i] = Integer.parseInt(strc[1]); //得到用户输入物品的价值
}
long result = this.getMaxMoney(weightSum,weight_array,money_array);
System.out.println();
System.out.println("该问题解决后可以得到的最大收益为:"+ result);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
br.close(); //注意一定要记得在finally中加入关闭io流的代码
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
//封装函数,优化01背包的二维数组为一维的滚动数组的反复使用
public int getMaxMoney(int weightSum,int[] weight_array,int[] money_array)
{
int result = 0;
int dp[] = new int[weightSum+1];
for(int i=0; i<weight_array.length; i++) //其实这一个循环,就相当于在递推,先计算出只有物品1-i,背包剩余重量为sum-0的所有结果
{
for(int j=weightSum; j>=0; j--) //在这一层,其实就是对外层循环的每一次循环的i进行更新
{
if(weight_array[i] > j) break; //这一层很好理解,当前j已经放不进去物品i那么之前的所有j也都放不进去。
//而放不进去j的处理,其实就是dp[i][j]=dp[i-1][j];那使用滚动一维数组,其实就相当于,当前dp[j]不用更新,
//而随着for循环i++,其实就相当于实现了dp[i][j]=dp[i-1][j]
dp[j] = Math.max(dp[j], dp[j-weight_array[i]]+money_array[i]); //得到子问题的最优解
}
}
result = dp[weightSum];
return result;
}
}
代码测试结果显示