import java.io.File;
import java.io.PrintWriter;
import java.util.Scanner;
public class Knapsack {
private int[] Value;//存储物品的价值
private int[] Weight;//存储物品的重量
private int allWeight;//背包容纳重量
private int allNum;//物品数量
private int BValue[][];//BValue[i][j]存储前i个物品的重量为j的最大价值
public Knapsack(int allWeight,int allNum){
this.setAllNum(allNum);
this.setAllWeight(allWeight);
this.Value=new int[allNum];
this.Weight=new int[allNum];
this.BValue=new int[allNum+1][allWeight+1];
}
public int[] getV() {
return Value;
}
public void setV(int[] v) {
this.Value = v;
}
public int[] getW() {
return Weight;
}
public void setW(int[] w) {
this.Weight = w;
}
public int[][] getBValue() {
return BValue;
}
public void setBValue(int[][] fValue) {
this.BValue = fValue;
}
public static void main(String[] args) {
String path="src/Knapsack.txt";
String resultPath="src/KnapsackResult.txt";
Scanner scanner=null;
PrintWriter pw=null;
try {
scanner=new Scanner(new File(path));
pw=new PrintWriter(new File(resultPath));
int allWeight=scanner.nextInt();//背包所能容纳的总重量
int allNum=scanner.nextInt();//物品数量
Knapsack kna= new Knapsack(allWeight,allNum);//初始化背包
int[] v=kna.getV();
int[] w=kna.getW();
int[][] BValue=kna.getBValue();
int i=1;
for(i=1;i<=allNum;i++){//初始化物品价值数组和重量数组
w[i-1]=scanner.nextInt();
v[i-1]=scanner.nextInt();
}
for(i=1;i<=allNum;i++){
BValue[i][0]=0;
}
for(i=1;i<=allWeight;i++){
BValue[0][i]=0;
}
for(i=1;i<=allNum;i++){
for(int j=1;j<=allWeight;j++){
if(j<w[i-1]){
BValue[i][j]=BValue[i-1][j];
}else{
BValue[i][j]=Math.max(BValue[i-1][j], BValue[i-1][j-w[i-1]]+v[i-1]);
}
}
}
System.out.println("背包中物品的最大价值是:"+BValue[allNum][allWeight]);
kna.traceBack(v, w, BValue, allWeight, allNum);//求出物品编号和背包总重量
System.out.println("构造的二维表格输出结果:");
for(i=1;i<=allNum;i++){ //输出二维数组到文本文件KnapsackResult.txt中
for(int j=1;j<=allWeight;j++){
System.out.print(BValue[i][j]+" ");
pw.print(BValue[i][j]+" ");
}
System.out.println();
pw.println();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(scanner!=null) scanner.close();
if(pw!=null) pw.close();
}
}
/**
* 回溯法逆序找到背包的物品编号
* @param v 存储物品的价值
* @param w 存储物品的重量
* @param fvalue fValue[i][j]存储前i个物品的重量为j的最大价值
* @param allWeight 背包容纳重量
* @param allNum 物品数量
*/
public void traceBack(int[] v,int[] w,int[][] fvalue,int allWeight,int allNum){
int wupinNo[]=new int[allNum+1];
int j=allWeight;
for(int i=allNum;i>0;i--){
if(fvalue[i][j]>fvalue[i-1][j]){
wupinNo[i]=1;
j-=w[i-1];
if(j<0){
break;
}
}
}
int sumWeight=0;//记录背包的总重量
System.out.println();
System.out.println("背包中物品的编号是:");
for(int i=1;i<=allNum;i++){
if(wupinNo[i]==1){
System.out.print(i+" ");
sumWeight+=w[i-1];
}
}
System.out.println();
System.out.println();
System.out.println("背包的总重量是:"+sumWeight);
System.out.println();
}
public void setAllWeight(int allWeight) {
this.allWeight = allWeight;
}
public int getAllWeight() {
return allWeight;
}
public void setAllNum(int allNum) {
this.allNum = allNum;
}
public int getAllNum() {
return allNum;
}
}
import java.io.PrintWriter;
import java.util.Scanner;
public class Knapsack {
private int[] Value;//存储物品的价值
private int[] Weight;//存储物品的重量
private int allWeight;//背包容纳重量
private int allNum;//物品数量
private int BValue[][];//BValue[i][j]存储前i个物品的重量为j的最大价值
public Knapsack(int allWeight,int allNum){
this.setAllNum(allNum);
this.setAllWeight(allWeight);
this.Value=new int[allNum];
this.Weight=new int[allNum];
this.BValue=new int[allNum+1][allWeight+1];
}
public int[] getV() {
return Value;
}
public void setV(int[] v) {
this.Value = v;
}
public int[] getW() {
return Weight;
}
public void setW(int[] w) {
this.Weight = w;
}
public int[][] getBValue() {
return BValue;
}
public void setBValue(int[][] fValue) {
this.BValue = fValue;
}
public static void main(String[] args) {
String path="src/Knapsack.txt";
String resultPath="src/KnapsackResult.txt";
Scanner scanner=null;
PrintWriter pw=null;
try {
scanner=new Scanner(new File(path));
pw=new PrintWriter(new File(resultPath));
int allWeight=scanner.nextInt();//背包所能容纳的总重量
int allNum=scanner.nextInt();//物品数量
Knapsack kna= new Knapsack(allWeight,allNum);//初始化背包
int[] v=kna.getV();
int[] w=kna.getW();
int[][] BValue=kna.getBValue();
int i=1;
for(i=1;i<=allNum;i++){//初始化物品价值数组和重量数组
w[i-1]=scanner.nextInt();
v[i-1]=scanner.nextInt();
}
for(i=1;i<=allNum;i++){
BValue[i][0]=0;
}
for(i=1;i<=allWeight;i++){
BValue[0][i]=0;
}
for(i=1;i<=allNum;i++){
for(int j=1;j<=allWeight;j++){
if(j<w[i-1]){
BValue[i][j]=BValue[i-1][j];
}else{
BValue[i][j]=Math.max(BValue[i-1][j], BValue[i-1][j-w[i-1]]+v[i-1]);
}
}
}
System.out.println("背包中物品的最大价值是:"+BValue[allNum][allWeight]);
kna.traceBack(v, w, BValue, allWeight, allNum);//求出物品编号和背包总重量
System.out.println("构造的二维表格输出结果:");
for(i=1;i<=allNum;i++){ //输出二维数组到文本文件KnapsackResult.txt中
for(int j=1;j<=allWeight;j++){
System.out.print(BValue[i][j]+" ");
pw.print(BValue[i][j]+" ");
}
System.out.println();
pw.println();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(scanner!=null) scanner.close();
if(pw!=null) pw.close();
}
}
/**
* 回溯法逆序找到背包的物品编号
* @param v 存储物品的价值
* @param w 存储物品的重量
* @param fvalue fValue[i][j]存储前i个物品的重量为j的最大价值
* @param allWeight 背包容纳重量
* @param allNum 物品数量
*/
public void traceBack(int[] v,int[] w,int[][] fvalue,int allWeight,int allNum){
int wupinNo[]=new int[allNum+1];
int j=allWeight;
for(int i=allNum;i>0;i--){
if(fvalue[i][j]>fvalue[i-1][j]){
wupinNo[i]=1;
j-=w[i-1];
if(j<0){
break;
}
}
}
int sumWeight=0;//记录背包的总重量
System.out.println();
System.out.println("背包中物品的编号是:");
for(int i=1;i<=allNum;i++){
if(wupinNo[i]==1){
System.out.print(i+" ");
sumWeight+=w[i-1];
}
}
System.out.println();
System.out.println();
System.out.println("背包的总重量是:"+sumWeight);
System.out.println();
}
public void setAllWeight(int allWeight) {
this.allWeight = allWeight;
}
public int getAllWeight() {
return allWeight;
}
public void setAllNum(int allNum) {
this.allNum = allNum;
}
public int getAllNum() {
return allNum;
}
}