问题:给定金额m
和数字数组b[]
打印"Yes"
如果m
可以通过添加数组中的任意数量的元素而不重复来形成它们。
这就是我想出来的;如何在其中添加记忆矩阵?
#include<stdio.h>
int check(int b[],int n,int m){
if(m==0){
return 1;
}
if(m<0){
return 0;
}
if(n<=0 && m>0){
return 0;
}
return check(b,n-1,m-b[n-1]) + check(b,n-1,m);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d",&n);
scanf("%d",&m);
int b[n];
for(int i=0;i<n;i++){
scanf("%d",&b[i]);
}
if(check(b,n,m)>0){
printf("Yes\n");
}else{
printf("No\n");
}
}
return 0;
}
任何人都可以帮我把记忆矩阵加入其中吗?
答案 0 :(得分:4)
memoization缓存的关键字包括n
的第一个b
元素,加上m
。从这些表单中形成一个字符串,并将其用作哈希表的键。
......但重点是什么?在每次递归中n
递减时,只有两种情况,其中memoization将有所帮助:
如果对完全相同的号码列表进行了非递归通话check
,并且在m
之前调用了check
。
m-b[n-1] == m
时,也就是说b[n-1] == 0
时。
第一种情况不太可能(并且随着列表的大小增加而减少,这是备忘录最有帮助的时候),第二种情况很容易避免。只需替换
return check(b,n-1,m-b[n-1]) + check(b,n-1,m);
与
return b[n-1] == 0
? check(b,n-1,m) * 2
: check(b,n-1,m) + check(b,n-1,m-b[n-1]);