如图所示,是一个经典的0-1背包问题,对这种问题,网上有很多其他的求解方法,我在这里使用动态规划的思想来求解。首先我们要寻找该问题的最优子结构性质。
对于一个背包问题的最优解,我们在这里减去其中的一个物品i,那么背包剩下的物品是不是当背包容量为C-w[i]时,对于(1,2,3...i-1)这些物品的最优解。如图是详细解释。
接下来我们需要寻找递推关系,这也是该问题中最困难的一步。
在这里我直接给出递推关系式,具体的递推式的推出可以参考这个视频
【自制】01背包问题算法动画讲解_哔哩哔哩_bilibili
其中i表示,可以选择0到i号物品进行求解问题,j表示背包容量大小。
然后就是代码示例。
public int knapsack(int w[],int v[],int c){
int [][]dp=new int[v.length][c+1];
//初始化
for (int i = 0; i <v.length ; i++) {
dp[i][0]=0;
}
for (int i = 0; i < c+1; i++) {
dp[0][i]=0;
}
for (int i = 1; i < v.length; i++) {
for (int j = 1; j < c+1; j++) {
if(w[i]<=j){
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
else{
dp[i][j]=dp[i-1][j];
}
}
}
return dp[v.length-1][c];
}
要注意,这里的dp数组都是0开始的,所以v,w数组坐标都是1开始,0号坐标填0即可。
测试示例代码
void test2(){
int w[]={0,2,3,4};
int v[]={0,3,5,6};
int res=knapsack(w,v,6);
System.out.println(res);
}