我正在尝试解决背包问题的一个变种,并为它编写了一个递归解决方案。但我的解决方案是返回错误的值。我想我的算法有缺陷。能帮我找到故障吗?
这是我的代码。
int calc_budget(int b, int i){
// If we have reached the end
if(i >= nParty){
tbl[b][i] = 0;
return tbl[b][i];
}
//If remaining capacity is not able to hold the ith capacity, move on to next element
if(budget[i] > b){
if(tbl[b][i+1] == 0){
tbl[b][i+1] = calc_budget(b,i+1);
}
return tbl[b][i+1];
}
else{ //If the ith capacity can be accomodated
//Do not include this item
if(tbl[b][i+1] == 0){
tbl[b][i] = calc_budget(b,i+1);
}
// Include this item and consider the next item
if(tbl[b-budget[i]][i+1] == 0){
tbl[b-budget[i]][i] = fun[i] + calc_budget(b-budget[i], i+1);
}
// We have the results for includinng ith item as well as excluding ith item. Return the best ( max here )
return max(tbl[b][i], tbl[b-budget[i]][i]);
}
}
Objective of the problem: To find the maximum fun by optimally using the given max budget
以下是我的意见。
budget[3] = {19,12,19}
fun[3] = {2,4,5}
calc_budget(30,0)
allowed budget: 30
程序的正确答案应该是5.我正在返回7.我在尝试调试时绘制了递归树。我的发现:在选择项目0(右子树)时,val = 2 +(11,1)。这(11,1)将导致max((11,2)和0)。 (11,2)是5所以最终的结果是2 + 5 = 7.在这种DP技术中,我的算法不应该选择11,2作为预算的总和超过给定的一个。但这是我为递归DP找到的基本骨架。这个算法有缺陷还是我弄错了。
由于
奇丹巴拉姆
答案 0 :(得分:0)
问题是,在通话calc_budget(b, i)
期间,您为除tbl
之外的其他索引编写[b][i]
字段。我将尝试使用calc_budget(b, i)
的递归定义来解释该问题。
我们首先定义递归关系。让F(b, i)
成为各方i, ..., n
和最高预算b
的最大乐趣。然后,
F(b, n+1) = 0
F(b, i) = F(b, i+1) // if budget[i] > b
= max( F(b, i+1), fun[i] + F(b - budget[i], i+1) ) // otherwise
到目前为止一直很好。calc_budget(b, i)
应该准确计算这个数字,它应该使用tbl
作为已计算值的缓存。换句话说,在第一次拨打电话calc_budget(b, i)
后,tbl[b][i] == F(b, i)
必须为真。
这是一些实现此目的的伪代码:
initialize tbl[b][i] = -1 for all b, i.
def calc_budget(b, i):
if tbl[b][i] != -1: return tbl[b][i]
if i == n + 1:
tbl[b][n+1] = 0
else:
if budget[i] > b:
tbl[b][i] = calc_budget(b, i+1)
else:
tbl[b][i] = max(
calc_budget(b, i+1),
fun[i] + calc_budget(b - budget[i], i+1)
)
return tbl[b][i]
我希望您现在同意,因为tbl
实际上只是已经计算过的值的缓存,所以写例如,这似乎很奇怪。 tbl[b-budget[i]][i]
致电calc_budget(b, i)
。
答案 1 :(得分:0)
首先,我认为0不足以表明天气已经计算过子问题,因为有些子问题的答案实际上是0。 其次,你的代码中有一个错误,你应该在返回值之前设置tbl [b] [i]的值。 试试这个:
// We have the results for includinng ith item as well as excluding ith item. Return the best ( max here )
tbl[b][i]=max(tbl[b][i], tbl[b-budget[i]][i]);
return tbl[b][i];
希望它有所帮助!