【发布时间】:2020-10-21 19:48:23
【问题描述】:
我正在解决子集总和问题:“给定一组数字,检查它是否可以分成两个子集,使得两个子集中的元素之和相同。”对于这个问题,我创建了一个可以正常工作但无法正确记忆的递归函数。
代码是:
bool func(int a[], int i, int n, long sum) // i is 0, n is the array size, sum is required sum
{
if(sum<0||i>=n)
return 0;
if(sum==0)
return 1;
if(func(a,i+1,n,sum-a[i]))
return 1;
if(func(a,i+1,n,sum))
return 1;
return 0;
}
请帮忙记下这段代码。您还可以告诉带有记忆或制表的递归代码哪种类型的问题更好。
【问题讨论】:
-
除此之外:
true和false是bool文字,1和0是ints -
提示:
a和n是递归中的常量,i和sum是变量。所以你需要一个二维数组来存储i([0, n)) 的所有可能值和 sum ([0, sum]) 的所有可能值。我个人认为 memoization 使算法更容易理解——假设你有一个现成的 memoization 库。如果没有,制表可能会更容易实现。 -
@VincentvanderWeele 你能告诉我什么是现成的记忆库
-
这将是一个函数(模板)
func_t memoise(func_t);,给定using func_t = std::function<bool(int*, int, int, long)>; -
旁白2:我觉得你的函数不对,第二个递归调用应该有
sum+a[i],前面的check应该是if (i == n) return sum == 0;
标签: c++ algorithm c++11 recursion dynamic-programming