C# 在背包里找到物品
我想用C#递归地解决背包问题。这是我的代码:C# 在背包里找到物品,c#,algorithm,recursion,knapsack-problem,C#,Algorithm,Recursion,Knapsack Problem,我想用C#递归地解决背包问题。这是我的代码: public int f(int n, int remain) { if (n < 0) return 0; if (w[n] > remain) { // Thread.VolatileWrite(ref check[n], 0); check[n] = 0; return f(n - 1, remain); } else {
public int f(int n, int remain)
{
if (n < 0) return 0;
if (w[n] > remain)
{
// Thread.VolatileWrite(ref check[n], 0);
check[n] = 0;
return f(n - 1, remain);
}
else
{
int a = f(n - 1, remain);
int b = p[n] + f(n - 1, remain - w[n]);
if (a >= b)
{
// Thread.VolatileWrite(ref check[n], 0);
check[n] = 0;
return a;
}
else
{
// Thread.VolatileWrite(ref check[n], 1);
check[n] = 1;
return b;
}
}
}
public int f(int n,int剩余)
{
如果(n<0)返回0;
如果(w[n]>保留)
{
//线程.VolatileWrite(参考检查[n],0);
检查[n]=0;
返回f(n-1,剩余);
}
其他的
{
int a=f(n-1,剩余);
intb=p[n]+f(n-1,剩余-w[n]);
如果(a>=b)
{
//线程.VolatileWrite(参考检查[n],0);
检查[n]=0;
返回a;
}
其他的
{
//线程写入(参考检查[n],1);
检查[n]=1;
返回b;
}
}
}
w
是一个包含权重的数组,p
是一个包含价格的数组n
是项目数,剩余
是最大重量
我的问题是
检查数组。我使用这个数组来存储将要放入包中的项目,但它并不总是有效,有时解决方案是正确的,有时则不是。我什么都试过了,但还是想不出来。如何解决此问题?检查数组的用法是错误的,因为它指示最后一次赋值,并且不必是所选的赋值
下面是一个反例,解释了为什么它不起作用
假设:
weights = [1,2]
values = [2,1]
w = 2
现在,让我们看看会发生什么:
f(1,2):
f(0,2):
f(-1,2) = 0
a = 0
f(-1,1) = 0
b = 2 + 0 = 2
b>a -> check[0] = 1
return f(0,2) = 2
a = 2
f(0,0):
w[0] > 0: check[0] = 0
return f(-1,0) = 0
return f(0,0) = 0
b = 1 + 0 = 1
a > b: check[1] = 0
return f(1,2) = 2
因此,这个问题的最佳解决方案是2(选择第二个元素),但您的解决方案没有选择任何元素(检查=[0,0])
这是因为检查的更改是全局性的,而不是调用环境的本地更改,具体来说,深层次的赋值不取决于您在更高层次上所做的选择
要处理此问题,您可以:
使您的列表不是全局的,每个递归调用都有自己的列表
列表的实例。“家长”呼叫将不仅选择哪一个
值,但根据此选择-父级也将
选择它将使用的列表,并将“他的”选择附加到列表中,然后转发给其父级
切换到a或模拟DP解决方案,然后使用您创建的表来确定要选择的元素,如我在本线程中所述:
请包括实际结果与期望结果不同的特定输入。f
的返回值是多少?找到的溶液的重量?返回值应正确。注意修改递归内部的检查数组。尝试每次复制数组,并以元组形式返回它。它不是最优的,但你可以看到它better@codorw是一个由wights组成的数组,p是一个由价格组成的数组……n是项目数,剩余是最大值wight@rpax是的,返回值是正确的…我不明白你的建议,你能给我一个例子吗?我现在在手机上…很好的答案。我喜欢家庭作业问题的答案,这里没有的是代码答案,教你如何思考和解决问题。谢谢你让这个网站变得更好。@Ami很抱歉要求你提供代码……但是多给一点提示对你建议的第一个解决方案没有坏处