这是我的任务
背包问题是计算机科学的经典之作。最简单的 形式它涉及尝试将不同重量的物品装入一个 背包,以便背包以指定的总重量结束。 您不需要适合所有项目。例如,假设你想要 你的背包重量只有20磅,你有五件物品, 重量为11,8,7,6和5磅。对于少量商品, 人类通过检查很好地解决了这个问题。那么你 可能只能弄清楚只有8,7和5项的组合 最多可增加20个。
我真的不知道从哪里开始编写这个算法。应用于阶乘和三角数时,我理解递归。但是我现在迷路了。
答案 0 :(得分:19)
你尝试了什么?
这个想法,考虑到你说的问题(指明我们必须使用递归)很简单:对于你可以采取的每个项目,看看是否更好地接受它。所以只有两条可能的路径:
当你拿走物品时,你将它从列表中删除,然后根据物品的重量减少容量。
如果您不接受该项目,则从列表中删除,但不会减少容量。
有时打印递归调用可能会有所帮助。在这种情况下,它可能如下所示:
Calling 11 8 7 6 5 with cap: 20
+Calling 8 7 6 5 with cap: 20
| Calling 7 6 5 with cap: 20
| Calling 6 5 with cap: 20
| Calling 5 with cap: 20
| Result: 5
| Calling 5 with cap: 14
| Result: 5
| Result: 11
| Calling 6 5 with cap: 13
| Calling 5 with cap: 13
| Result: 5
| Calling 5 with cap: 7
| Result: 5
| Result: 11
| Result: 18
| Calling 7 6 5 with cap: 12
| Calling 6 5 with cap: 12
| Calling 5 with cap: 12
| Result: 5
| Calling 5 with cap: 6
| Result: 5
| Result: 11
| Calling 6 5 with cap: 5
| Calling 5 with cap: 5
| Result: 5
| Result: 5
| Result: 12
+Result: 20
Calling 8 7 6 5 with cap: 9
Calling 7 6 5 with cap: 9
Calling 6 5 with cap: 9
Calling 5 with cap: 9
Result: 5
Calling 5 with cap: 3
Result: 0
Result: 6
Calling 6 5 with cap: 2
Calling 5 with cap: 2
Result: 0
Result: 0
Result: 7
Calling 7 6 5 with cap: 1
Calling 6 5 with cap: 1
Calling 5 with cap: 1
Result: 0
Result: 0
Result: 0
Result: 8
Result: 20
我故意表示调用[8 7 6 5],容量为20,结果为20(8 + 7 + 5)。
请注意,[8 7 6 5]被调用两次:一次容量为20(因为我们没有服用11次),一次容量为9次(因为确实服用了11次)。
解决方案的路径:
11未参加,呼叫[8 7 6 5],容量为20
8,调用[7 6 5],容量为12(20 - 8)
7,调用[6 5],容量为5(12 - 7)
6未采用,调用[5]容量为5
5,我们零。
Java中的实际方法可以适用于非常少的代码行。
由于这显然是家庭作业,我只会用骨架帮助你:
private int ukp( final int[] ar, final int cap ) {
if ( ar.length == 1 ) {
return ar[0] <= cap ? ar[0] : 0;
} else {
final int[] nar = new int[ar.length-1];
System.arraycopy(ar, 1, nar, 0, nar.length);
fint int item = ar[0];
if ( item < cap ) {
final int left = ... // fill me: we're not taking the item
final int took = ... // fill me: we're taking the item
return Math.max(took,left);
} else {
return ... // fill me: we're not taking the item
}
}
}
我确实将数组复制到一个新的数组,效率较低(但无论如何,如果你寻求性能,递归不是去这里的方式),而是更“有效”。
答案 1 :(得分:12)
我必须为我的作业做这个,所以我测试了所有上面的代码(除了Python之外),但它们都不适用于每个角落的情况。
这是我的代码,它适用于每个角落的情况。
static int[] values = new int[] {894, 260, 392, 281, 27};
static int[] weights = new int[] {8, 6, 4, 0, 21};
static int W = 30;
private static int knapsack(int i, int W) {
if (i < 0) {
return 0;
}
if (weights[i] > W) {
return knapsack(i-1, W);
} else {
return Math.max(knapsack(i-1, W), knapsack(i-1, W - weights[i]) + values[i]);
}
}
public static void main(String[] args) {
System.out.println(knapsack(values.length - 1, W));}
它没有优化,递归会杀了你,但你可以用简单的memoization来解决这个问题。为什么我的代码简短,正确且易于理解?我刚刚查看了0-1背包问题http://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming
的数学定义答案 2 :(得分:8)
问题基本上是经典背包问题的修改版本,为了简单起见(没有值/好处对应权重)(对于实际:http://en.wikipedia.org/wiki/Knapsack_problem,0/1 Knapsack - A few clarification on Wiki's pseudocode,{ {3}},How to understand the knapsack problem is NP-complete?,Why is the knapsack problem pseudo-polynomial?)。
以下是在c#中解决此问题的五个版本:
版本1 :使用动态编程(制表 - 通过急切地找到所有求和问题的解决方案到达最终版本) - O(n * W)
版本2 :使用DP但是记忆版本(懒惰 - 只需找到所需的解决方案)
版本3 使用递归来演示重叠的子问题和最佳子结构
版本4 递归(暴力) - 基本上接受的答案
第5版使用#4堆栈(演示删除尾递归)
版本1 :使用动态编程(制表 - 通过急切地找到所有求和问题的解决方案到达最终版本) - O(n * W)
public bool KnapsackSimplified_DP_Tabulated_Eager(int[] weights, int W)
{
this.Validate(weights, W);
bool[][] DP_Memoization_Cache = new bool[weights.Length + 1][];
for (int i = 0; i <= weights.Length; i++)
{
DP_Memoization_Cache[i] = new bool[W + 1];
}
for (int i = 1; i <= weights.Length; i++)
{
for (int w = 0; w <= W; w++)
{
/// f(i, w) determines if weight 'w' can be accumulated using given 'i' number of weights
/// f(i, w) = False if i <= 0
/// OR True if weights[i-1] == w
/// OR f(i-1, w) if weights[i-1] > w
/// OR f(i-1, w) || f(i-1, w-weights[i-1])
if(weights[i-1] == w)
{
DP_Memoization_Cache[i][w] = true;
}
else
{
DP_Memoization_Cache[i][w] = DP_Memoization_Cache[i - 1][w];
if(!DP_Memoization_Cache[i][w])
{
if (w > weights[i - 1])
{
DP_Memoization_Cache[i][w] = DP_Memoization_Cache[i - 1][w - weights[i - 1]];
}
}
}
}
}
return DP_Memoization_Cache[weights.Length][W];
}
版本2 :使用DP但记忆版本(懒惰 - 只需找到所需的解决方案)
/// <summary>
/// f(i, w) determines if weight 'w' can be accumulated using given 'i' number of weights
/// f(i, w) = False if i < 0
/// OR True if weights[i] == w
/// OR f(i-1, w) if weights[i] > w
/// OR f(i-1, w) || f(i-1, w-weights[i])
/// </summary>
/// <param name="rowIndexOfCache">
/// Note, its index of row in the cache
/// index of given weifhts is indexOfCahce -1 (as it starts from 0)
/// </param>
bool KnapsackSimplified_DP_Memoization_Lazy(int[] weights, int w, int i_rowIndexOfCache, bool?[][] DP_Memoization_Cache)
{
if(i_rowIndexOfCache < 0)
{
return false;
}
if(DP_Memoization_Cache[i_rowIndexOfCache][w].HasValue)
{
return DP_Memoization_Cache[i_rowIndexOfCache][w].Value;
}
int i_weights_index = i_rowIndexOfCache - 1;
if (weights[i_weights_index] == w)
{
//we can just use current weight, so no need to call other recursive methods
//just return true
DP_Memoization_Cache[i_rowIndexOfCache][w] = true;
return true;
}
//see if W, can be achieved without using weights[i]
bool flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights,
w, i_rowIndexOfCache - 1);
DP_Memoization_Cache[i_rowIndexOfCache][w] = flag;
if (flag)
{
return true;
}
if (w > weights[i_weights_index])
{
//see if W-weight[i] can be achieved with rest of the weights
flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights,
w - weights[i_weights_index], i_rowIndexOfCache - 1);
DP_Memoization_Cache[i_rowIndexOfCache][w] = flag;
}
return flag;
}
<强>,其中强>
public bool KnapsackSimplified_DP_Memoization_Lazy(int[] weights, int W)
{
this.Validate(weights, W);
//note 'row' index represents the number of weights been used
//note 'colum' index represents the weight that can be achived using given
//number of weights 'row'
bool?[][] DP_Memoization_Cache = new bool?[weights.Length+1][];
for(int i = 0; i<=weights.Length; i++)
{
DP_Memoization_Cache[i] = new bool?[W + 1];
for(int w=0; w<=W; w++)
{
if(i != 0)
{
DP_Memoization_Cache[i][w] = null;
}
else
{
//can't get to weight 'w' using none of the given weights
DP_Memoization_Cache[0][w] = false;
}
}
DP_Memoization_Cache[i][0] = false;
}
bool f = this.KnapsackSimplified_DP_Memoization_Lazy(
weights, w: W, i_rowIndexOfCache: weights.Length, DP_Memoization_Cache: DP_Memoization_Cache);
Assert.IsTrue(f == DP_Memoization_Cache[weights.Length][W]);
return f;
}
版本3 识别重叠的子问题和最佳子结构
/// <summary>
/// f(i, w) = False if i < 0
/// OR True if weights[i] == w
/// OR f(i-1, w) if weights[i] > w
/// OR f(i-1, w) || f(i-1, w-weights[i])
/// </summary>
public bool KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(int[] weights, int W, int i)
{
if(i<0)
{
//no more weights to traverse
return false;
}
if(weights[i] == W)
{
//we can just use current weight, so no need to call other recursive methods
//just return true
return true;
}
//see if W, can be achieved without using weights[i]
bool flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights,
W, i - 1);
if(flag)
{
return true;
}
if(W > weights[i])
{
//see if W-weight[i] can be achieved with rest of the weights
return this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights, W - weights[i], i - 1);
}
return false;
}
其中
public bool KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(int[] weights, int W)
{
this.Validate(weights, W);
bool f = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights, W,
i: weights.Length - 1);
return f;
}
第4版暴力
private bool KnapsackSimplifiedProblemRecursive(int[] weights, int sum, int currentSum, int index, List<int> itemsInTheKnapsack)
{
if (currentSum == sum)
{
return true;
}
if (currentSum > sum)
{
return false;
}
if (index >= weights.Length)
{
return false;
}
itemsInTheKnapsack.Add(weights[index]);
bool flag = KnapsackSimplifiedProblemRecursive(weights, sum, currentSum: currentSum + weights[index],
index: index + 1, itemsInTheKnapsack: itemsInTheKnapsack);
if (!flag)
{
itemsInTheKnapsack.Remove(weights[index]);
flag = KnapsackSimplifiedProblemRecursive(weights, sum, currentSum, index + 1, itemsInTheKnapsack);
}
return flag;
}
public bool KnapsackRecursive(int[] weights, int sum, out List<int> knapsack)
{
if(sum <= 0)
{
throw new ArgumentException("sum should be +ve non zero integer");
}
knapsack = new List<int>();
bool fits = KnapsackSimplifiedProblemRecursive(weights, sum, currentSum: 0, index: 0,
itemsInTheKnapsack: knapsack);
return fits;
}
版本5:使用堆栈的迭代版本(注意 - 相同的复杂性 - 使用堆栈 - 删除尾部递归)
public bool KnapsackIterativeUsingStack(int[] weights, int sum, out List<int> knapsack)
{
sum.Throw("sum", s => s <= 0);
weights.ThrowIfNull("weights");
weights.Throw("weights", w => (w.Length == 0)
|| w.Any(wi => wi < 0));
var knapsackIndices = new List<int>();
knapsack = new List<int>();
Stack<KnapsackStackNode> stack = new Stack<KnapsackStackNode>();
stack.Push(new KnapsackStackNode() { sumOfWeightsInTheKnapsack = 0, nextItemIndex = 1 });
stack.Push(new KnapsackStackNode() { sumOfWeightsInTheKnapsack = weights[0], nextItemIndex = 1, includesItemAtCurrentIndex = true });
knapsackIndices.Add(0);
while(stack.Count > 0)
{
var top = stack.Peek();
if(top.sumOfWeightsInTheKnapsack == sum)
{
int count = 0;
foreach(var index in knapsackIndices)
{
var w = weights[index];
knapsack.Add(w);
count += w;
}
Debug.Assert(count == sum);
return true;
}
//basically either of the below three cases, we dont need to traverse/explore adjuscent
// nodes further
if((top.nextItemIndex == weights.Length) //we reached end, no need to traverse
|| (top.sumOfWeightsInTheKnapsack > sum) // last added node should not be there
|| (top.alreadyExploredAdjuscentItems)) //already visted
{
if (top.includesItemAtCurrentIndex)
{
Debug.Assert(knapsackIndices.Contains(top.nextItemIndex - 1));
knapsackIndices.Remove(top.nextItemIndex - 1);
}
stack.Pop();
continue;
}
var node1 = new KnapsackStackNode();
node1.sumOfWeightsInTheKnapsack = top.sumOfWeightsInTheKnapsack;
node1.nextItemIndex = top.nextItemIndex + 1;
stack.Push(node1);
var node2 = new KnapsackStackNode();
knapsackIndices.Add(top.nextItemIndex);
node2.sumOfWeightsInTheKnapsack = top.sumOfWeightsInTheKnapsack + weights[top.nextItemIndex];
node2.nextItemIndex = top.nextItemIndex + 1;
node2.includesItemAtCurrentIndex = true;
stack.Push(node2);
top.alreadyExploredAdjuscentItems = true;
}
return false;
}
其中
class KnapsackStackNode
{
public int sumOfWeightsInTheKnapsack;
public int nextItemIndex;
public bool alreadyExploredAdjuscentItems;
public bool includesItemAtCurrentIndex;
}
和单元测试
[TestMethod]
public void KnapsackSimpliedProblemTests()
{
int[] weights = new int[] { 7, 5, 4, 4, 1 };
List<int> bag = null;
bool flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 10, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(5));
Assert.IsTrue(bag.Contains(4));
Assert.IsTrue(bag.Contains(1));
Assert.IsTrue(bag.Count == 3);
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 3, knapsack: out bag);
Assert.IsFalse(flag);
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 7, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(7));
Assert.IsTrue(bag.Count == 1);
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 1, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(1));
Assert.IsTrue(bag.Count == 1);
flag = this.KnapsackSimplified_DP_Tabulated_Eager(weights, 10);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_DP_Tabulated_Eager(weights, 3);
Assert.IsFalse(flag);
flag = this.KnapsackSimplified_DP_Tabulated_Eager(weights, 7);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_DP_Tabulated_Eager(weights, 1);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_DP_Memoization_Lazy(weights, 10);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_DP_Memoization_Lazy(weights, 3);
Assert.IsFalse(flag);
flag = this.KnapsackSimplified_DP_Memoization_Lazy(weights, 7);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_DP_Memoization_Lazy(weights, 1);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights, 10);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights, 3);
Assert.IsFalse(flag);
flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights, 7);
Assert.IsTrue(flag);
flag = this.KnapsackSimplified_OverlappedSubPromblems_OptimalSubstructure(weights, 1);
Assert.IsTrue(flag);
flag = this.KnapsackRecursive(weights, 10, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(5));
Assert.IsTrue(bag.Contains(4));
Assert.IsTrue(bag.Contains(1));
Assert.IsTrue(bag.Count == 3);
flag = this.KnapsackRecursive(weights, 3, knapsack: out bag);
Assert.IsFalse(flag);
flag = this.KnapsackRecursive(weights, 7, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(7));
Assert.IsTrue(bag.Count == 1);
flag = this.KnapsackRecursive(weights, 1, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(1));
Assert.IsTrue(bag.Count == 1);
weights = new int[] { 11, 8, 7, 6, 5 };
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 20, knapsack: out bag);
Assert.IsTrue(bag.Contains(8));
Assert.IsTrue(bag.Contains(7));
Assert.IsTrue(bag.Contains(5));
Assert.IsTrue(bag.Count == 3);
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 27, knapsack: out bag);
Assert.IsFalse(flag);
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 11, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(11));
Assert.IsTrue(bag.Count == 1);
flag = this.KnapsackSimplifiedProblemIterativeUsingStack(weights, 5, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(5));
Assert.IsTrue(bag.Count == 1);
flag = this.KnapsackRecursive(weights, 20, knapsack: out bag);
Assert.IsTrue(bag.Contains(8));
Assert.IsTrue(bag.Contains(7));
Assert.IsTrue(bag.Contains(5));
Assert.IsTrue(bag.Count == 3);
flag = this.KnapsackRecursive(weights, 27, knapsack: out bag);
Assert.IsFalse(flag);
flag = this.KnapsackRecursive(weights, 11, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(11));
Assert.IsTrue(bag.Count == 1);
flag = this.KnapsackRecursive(weights, 5, knapsack: out bag);
Assert.IsTrue(flag);
Assert.IsTrue(bag.Contains(5));
Assert.IsTrue(bag.Count == 1);
}
答案 3 :(得分:2)
这是一个简单的递归实现(效率不高,但很容易理解)。它是在Python中,OP要求Java实现,但将其移植到Java应该不会太困难,就像查看伪代码一样。
main函数声明三个参数:V是值数组,W是权重数组,C是背包的容量。
def knapsack(V, W, C):
return knapsack_aux(V, W, len(V)-1, C)
def knapsack_aux(V, W, i, aW):
if i == -1 or aW == 0:
return 0
elif W[i] > aW:
return knapsack_aux(V, W, i-1, aW)
else:
return max(knapsack_aux(V, W, i-1, aW),
V[i] + knapsack_aux(V, W, i-1, aW-W[i]))
算法最大化添加到背包中的项目的值,返回给定权重可达到的最大值
答案 4 :(得分:2)
public class Knapsack {
public int[] arr = {11,8,7,6,5};
public int[] retArr = new int[5];
int i = 0;
public boolean problem(int sum, int pick) {
if(pick == arr.length) {
return false;
}
if(arr[pick] < sum) {
boolean r = problem(sum - arr[pick], pick+1);
if(!r) {
return problem(sum, pick+1);
} else {
retArr[i++] = arr[pick];
return true;
}
} else if (arr[pick] > sum) {
return problem(sum, pick+1);
} else {
retArr[i++] = arr[pick];
return true;
}
}
public static void main(String[] args) {
Knapsack rk = new Knapsack`enter code here`();
if(rk.problem(20, 0)) {
System.out.println("Success " );
for(int i=0; i < rk.retArr.length; i++)
System.out.println(rk.retArr[i]);
}
}
}
答案 5 :(得分:0)
Java中的另一个动态编程实现。 我总觉得使用备忘录的自上而下的DP比自下而上的DP更容易理解。
完整,不言自明,可运行的代码,使用this example from Wikipedia中的数据:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Knapsack {
private static final List<Item> ITEMS = new ArrayList<>();
private static final Map<Integer, Bag> CACHE = new HashMap<>();
private static final boolean FINITE_ITEMS = true; //whether an item can be added more than once
public static void main(String[] args) {
ITEMS.add(new Item(4, 12, "GREEN"));
ITEMS.add(new Item(2, 2, "CYAN"));
ITEMS.add(new Item(2, 1, "GREY"));
ITEMS.add(new Item(1, 1, "ORANGE"));
ITEMS.add(new Item(10, 4, "YELLOW"));
Bag best = bestBagForCapa(15);
System.out.println(best.toString());
}
public static Bag bestBagForCapa(int capa) {
if (CACHE.containsKey(capa)) return CACHE.get(capa);
if (capa < 0) return null;
if (capa == 0) return new Bag(0, 0);
int currentWeight = -1;
int currentValue = -1;
String newItem = null;
List<String> previousItems = null;
for (Item p : ITEMS) {
Bag previous = bestBagForCapa(capa - p.weight);
if (previous == null) continue;
int weightSoFar = previous.weight;
int valueSoFar = previous.value;
int nextBestValue = 0;
Item candidateItem = null;
for (Item candidate : ITEMS) {
if (FINITE_ITEMS && previous.alreadyHas(candidate)) continue;
if (weightSoFar + candidate.weight <= capa && nextBestValue < valueSoFar + candidate.value) {
candidateItem = candidate;
nextBestValue = valueSoFar + candidate.value;
}
}
if (candidateItem != null && nextBestValue > currentValue) {
currentValue = nextBestValue;
currentWeight = weightSoFar + candidateItem.weight;
newItem = candidateItem.name;
previousItems = previous.contents;
}
}
if (currentWeight <= 0 || currentValue <= 0) throw new RuntimeException("cannot be 0 here");
Bag bestBag = new Bag(currentWeight, currentValue);
bestBag.add(previousItems);
bestBag.add(Collections.singletonList(newItem));
CACHE.put(capa, bestBag);
return bestBag;
}
}
class Item {
int value;
int weight;
String name;
Item(int value, int weight, String name) {
this.value = value;
this.weight = weight;
this.name = name;
}
}
class Bag {
List<String> contents = new ArrayList<>();
int weight;
int value;
boolean alreadyHas(Item item) {
return contents.contains(item.name);
}
@Override
public String toString() {
return "weight " + weight + " , value " + value + "\n" + contents.toString();
}
void add(List<String> name) {
contents.addAll(name);
}
Bag(int weight, int value) {
this.weight = weight;
this.value = value;
}
}
答案 6 :(得分:0)
def knpsack(weight , value , k , index=0 , currweight=0):
if(index>=len(weight)):
return 0
take = 0
dontake = 0
if(currweight+weight[index] <= k):
take = value[index] +
knpsack(weight,value,k,index+1,currweight+weight[index])
dontake = knpsack(weight,value,k,index+1,currweight)
return max(take,dontake)
答案 7 :(得分:-1)
这是一个Java解决方案
static int knapsack(int[] values, int[] weights, int W, int[] tab, int i) {
if(i>=values.length) return 0;
if(tab[W] != 0)
return tab[W];
int value1 = knapsack(values, weights, W, tab, i+1);
int value2 = 0;
if(W >= weights[i]) value2 = knapsack(values, weights, W-weights[i], tab, i+1) + values[i];
return tab[W] = (value1>value2) ? value1 : value2;
}
使用
进行测试public static void main(String[] args) {
int[] values = new int[] {894, 260, 392, 281, 27};
int[] weights = new int[] {8, 6, 4, 0, 21};
int W = 30;
int[] tab = new int[W+1];
System.out.println(knapsack(values, weights, W, tab, 0));
}
答案 8 :(得分:-1)
这是Java中的一个简单的递归解决方案,但如果可能的话,你应该避免使用递归。
public class Knapsack {
public static void main(String[] args) {
int[] arr = new int[]{11, 8, 7, 6, 5};
find(arr,20);
}
public static boolean find( int[] arr,int total){
return find(arr,0,total);
}
private static boolean find( int[] arr,int start, int total){
if (start == arr.length){
return false;
}
int curr = arr[start];
if (curr == total){
System.out.println(curr);
return true;
}else if (curr > total || !find(arr,start+1,total-curr)){
return find(arr,start+1,total);
}
System.out.println(curr);
return true;
}
}