文章目錄
一、遞歸解決揹包問題
暴力遞歸,窮舉出所有的可能性,在檢索完所有物品,即index=nums.length時候決定是否更新最大值
1、當物品體積小於等於當前揹包容量,選擇放或者不放
2、當物品體積大於,只能選擇不放該物品
//遞歸解決揹包問題
public int getMaxValue(int[] weight, int[] value, int capacity) {
int index = 0;
int max = Integer.MIN_VALUE;
max = process(weight, value, index, 0, 0, capacity, max);
return max;
}
/**
*
* @param weight 質量數組
* @param value 價值數組
* @param index 當前位置
* @param prevalue 之前揹包價值
* @param precapacity 之前揹包容量
* @param capacity 揹包總容量
* @param max 最大值
* @return
*/
public int process(int[] weight, int[] value, int index, int prevalue, int precapacity, int capacity, int max) {
if (index == weight.length) {
max = Math.max(max, prevalue);
return max;
}
//當前物品體積小於等於揹包容量
if (precapacity + weight[index] <= capacity) {
max = process(weight, value, index + 1, prevalue + value[index], precapacity + weight[index], capacity,
max);
}
//
max = process(weight, value, index + 1, prevalue, precapacity, capacity, max);
return max;
}
二、動態規劃
1、res[i][j]表示當前物品爲i,當前揹包容量爲j的最大價值
2、res[i-1][j]代表的就是不將這件物品放入揹包,而res[i-1][j-weight[i-1]]+value[i-1]則是代表將第i件放入揹包之後的總價值,比較兩者的價值,得出最大的價值存入現在的揹包之中
3、流程
if(當前物品體積大於容量) {
res[i][j] = res[i-1][j];//當前揹包最大價值等於前一件物品放入揹包的價值
}else {
//當前物品放與不放的較大價值
res[i][j] = Math.max( res[i-1][j],res[i-1][j-weight[i-1]]+value[i-1]);
}
//動態規劃解決揹包問題
public int getMaxValueDP(int[] weight, int[] value, int capacity) {
int num = weight.length;
//一維表示物品i,二維表示揹包容量
//w[i]>j ,則 m[i][j] = m[i-1][j],無法放下當前物品,因此最大價值爲前一個物品最大價值
//w[i]>j,則m[i][j] = Math.max( m[i-1][j],m[i][j-weight[i]]+v[i]),如果能夠放下當前物品,則會選擇放或者不放,最終選擇較大值
int[][] res = new int[num+1][capacity+1];
for (int i = 1; i < res.length; i++) {
for (int j = 0; j < res[0].length; j++) {
if(weight[i-1]>j) {
res[i][j] = res[i-1][j];
}else {
res[i][j] = Math.max( res[i-1][j],res[i-1][j-weight[i-1]]+value[i-1]);
}
}
}
return res[num][capacity];
}