0-1背包问题

问题描述:
有5个物品,其重量分别是(2,2,6,5,4),价值分别为(6,3,5,4,6),背包的容量为10.
求解思路:
首先求解初始子问题,把前面i个物品装入容量为0的背包和把0个物品装入容量为j的背包,即v(i,0)=v(0,j)=0,将第0行和第0列初始化为0.
再对第一阶段的子问题进行求解,装入前一个物品,确定各种情况下背包能够获得的最大价值。在求解第二阶段的子问题,装入前2个物品,确定各种情况下背包能够获得的最大价值。
以此类推,直到第n个阶段,v(5,10)便是在容量为10的背包中装入5个物品时取得最大价值,为了求的装入背包的物品,从v(5,10)开始回溯。由于v(5,10)>v(4,10).则物品5装入背包,j=j-w5=6;由于v(4,6)=v3,6)=v(2,6),则物品4,3没有装入背包,由于v(2,6)>v(1,6),则物品2装入背包,j=j-w2=4,由于v(1,4)>V(0,4),则物品1装入背包,问题的最优解x={1,1,0,0,1}。
程序实现:
package com.hpu.bag01;

public class Knapsack {
public static int[][] knapsack(int[] w,int[] v,int c){
int i,j,n=w.length;
int[][] m=new int[n+1][c+1];
for(i=1;i<n+1;i++)
m[i][0]=0;
for(j=0;j<c+1;j++)
m[0][j]=0;
for(i=1;i<=n;i++)
for(j=1;j<=c;j++){
m[i][j]=m[i-1][j];
if(w[i-1]<=j)
if (v[i-1]+m[i-1][j-w[i-1]]>m[i-1][j])
m[i][j]=v[i-1]+m[i-1][j-w[i-1]];
}
return m;
}
public static int[] buildSolution(int[][] m,int[] w,int c){
int i,j=c,n=w.length;
int[] x=new int[n];
for(i=n;i>=1;i–)
if (m[i][j]==m[i-1][j])
x[i-1]=0;
else {
x[i-1]=1;
j-=w[i-1];
}
return x;
}
}
package com.hpu.bag01;

public class Test {
public static void main(String[] args) {
int w[]={2,2,6,5,4},v[]={6,3,5,4,6};
int[][] m;
int[] x;
m=Knapsack.knapsack(w,v,10);
x=Knapsack.buildSolution(m,w,10);
for(int i=0;i<5;i++)
System.out.print(x[i]+" ");
System.out.println();
}
}
运行结果:
在这里插入图片描述

时间复杂度分析:
在算法Knapsack中,第一个for循环的时间性能是O(n),第二个for循环的时间性能是O(C),第三个循环是两层嵌套的for循环,其时间性能是O(n x C),第四个for循环的时间性能是O(n),所以,算法的时间复杂性也就是O(n x C)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值