如何将记忆应用于此递归函数?

How can I apply memoization to this recursive function?

本文关键字:递归函数 应用于 记忆      更新时间:2023-10-16

我正在解决子集总和问题:"给定一组数字,检查它是否可以划分为两个子集,以便两个子集中的元素总和相同。 对于这个问题,我创建了一个可以正常工作的递归函数,但我无法正确记住它。

代码为:

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;
}

请帮助记住此代码。您还可以通过记忆或制表来判断哪种类型的问题更适合这些类型的递归代码。

记忆只是意味着存储已经计算的结果,这样您以后就不必重新计算它们。因此,每当func调用自己并获得答案时,请向字典添加一个条目,该条目将func的输入映射到其输出。然后,在调用 func 之前,查看字典中是否已有您将要使用的输入的条目,如果是,请不要再次调用func;请改用您在字典中缓存的输出。

制表要容易得多。

bool ss(int a[],int n,int s){
bool r[n+1][s+1];
for(int i=0;i<=n;++i)
r[i][0]=true;
for(int i=1;i<=s;++i)
r[0][s]=false;
for(int i=1;i<=n;++i)
for(int j=1;j<=s;++j)
if(j>=a[i])
r[i][j]=r[i-1][j] || r[i-1][j-a[i]];
else r[i][j]=r[i-1][j];
return r[n][s];
}