源代码
有过大概了解过该算法的应该可以轻易理解
//动态规划解决0-1背包
public class BackOf01 {
public static void main(String[] args) {
int n = 4;//商品数量
int[] p = {0,3,4,5,6};//各商品的价值
int[] v = {0,2,3,4,5};//各商品的体积
int C = 8;//背包的容量
int[][] Rec = new int[n+1][C+1];//记录选择的商品用0-1
int[][] P = new int[n+1][C+1];//创建二维数组并初始化二维数组边界
DPF(n,p,v,C,Rec,P);//动态规划
KnapsackDP(n,p,v,C,Rec,P);//构造备忘录
print(n,Rec,C,v);//打印结果
}
//递归构造0-1二维表格(备忘录)
public static void KnapsackDP(int n,int[] p,int[] v,int C,int[][] Rec,int[][] P) {
//根据优化表格进行商品判断
for(int i=1;i<=n;i++) {
for(int j=1;j<=C;j++) {
if( (v[i]<=j) && (p[i] + P[i-1][j-v[i]] > P[i-1][j]) ) { //如果能放下i件商品时
Rec[i][j] = 1;
KnapsackDP(n-1,p,v,C-v[i],Rec,P);//放下该商品后,进入前一层对剩余空间进行分配
}else {//放不下i件商品时,
Rec[i][j] = 0;
KnapsackDP(n-1,p,v,C,Rec,P);
}
}
}
}
//打印选择的商品
public static void print(int n,int[][] Rec,int C,int[] v) {
System.out.println("最优结果选择: ");
for(int i=n;i>0;i--) {
if(Rec[i][C] == 1) {
System.out.println("选择商品 :" + (i));
C = C - v[i];//分配除了刚选择的i商品之后的背包空间
}
else {
System.out.println("不选择商品 :" + (i));
}
}
//打印备忘录
System.out.println("备忘录: ");
for(int i=0;i<Rec.length;i++) {
for(int j=0;j<Rec[i].length;j++) {
System.out.print(Rec[i][j] + "\t");
}
System.out.println();
}
}
//动态规划
public static void DPF(int n,int[] p,int[] v,int C,int[][] Rec,int[][] P) {//求解最优表格
System.out.println("最优解表格: ");
//当背包容量为0时,无论商品数为多少,都装不下
for(int i=0;i<n+1;i++) {
P[i][0] = 0;
}
//当当商品数量为0时,无论背包空间为多大,都装不下
for(int i=0;i<C+1;i++) {
P[0][i] = 0;
}
for(int i=1;i<=n;i++) {
for(int j=1;j<=C;j++) {
if( (v[i]<=j) && (p[i] + P[i-1][j-v[i]] > P[i-1][j]) ) {
P[i][j] = p[i] + P[i-1][j-v[i]];
}else {
P[i][j] = P[i-1][j];
}
}
}
//打印最大值的变化表
for(int i=0;i<P.length;i++) {
for(int j=0;j<P[i].length;j++) {
System.out.print(P[i][j] + "\t");
}
System.out.println();
}
}
}