记忆化搜索

1.记忆化搜索的思想

记忆化搜索的思想是,在搜索过程中,会有很多重复计算,如果我们能记录一些状态的答案,就可以减少重复搜索量

2、记忆化搜索的适用范围

根据记忆化搜索的思想,它是解决重复计算,而不是重复生成,也就是说,这些搜索必须是在搜索扩展路径的过程中分步计算的题目,也就是“搜索答案与路径相关”的题目,而不能是搜索一个路径之后才能进行计算的题目,必须要分步计算,并且搜索过程中,一个搜索结果必须可以建立在同类型问题的结果上,也就是类似于动态规划解决的那种。
也就是说,他的问题表达,不是单纯生成一个走步方案,而是生成一个走步方案的代价等,而且每走一步,在搜索树/图中生成一个新状态,都可以精确计算出到此为止的费用,也就是,可以分步计算,这样才可以套用已经得到的答案

3、记忆化搜索的核心实现

a. 首先,要通过一个表记录已经存储下的搜索结果,一般用哈希表实现
b.状态表示,由于是要用哈希表实现,所以状态最好可以用数字表示,常用的方法是把一个状态连写成一个p进制数字,然后把这个数字对应的十进制数字作为状态
c.在每一状态搜索的开始,高效的使用哈希表搜索这个状态是否出现过,如果已经做过,直接调用答案,回溯
d.如果没有,则按正常方法搜索

4、记忆化搜索是类似于动态规划的,不同的是,它是倒做的“递归式动态规划”。

求二项式系数

简单递归

int bino(int n,int r){
	if(r == 0|| n == r) return 1;
	return bino(n-1,r-1) + bino(n-1,r);
}

记忆化

int cache[30][30];//初始为1
int bino2(int n,int r){
	if(r ==0 || n == r) return 1;
	if(cache[n][r] != -1)
	  return cache[n][r];
	//直接计算并保存到数组
	return cache[n][r] = bino2(n-1,r-1) + bino2(n-1,r);
}

采用引用的方法

适用于多维时下标较乱的时候

int cache[30][30];//初始为1
int bino2(int n,int r){
	if(r ==0 || n == r) return 1;
	int & ret = cache[n][r]; //引用型
	if(ret != -1)
	  return ret;
	//直接计算并保存到数组
	return ret = bino2(n-1,r-1) + bino2(n-1,r);
}

三角形的最大路径

题意
有个以自然数排列而成的三角形。从最上面的数开始,每次向下或右下走一步,最终到达底部。每次可向下或向右下走一步。请在所有路径中找出数值之和最大的路径,并求出这个和。

代码:

int n,triangle[100][100];
int cache[100][100];

// 返回从 x,y其实到底部路径的最大值
int path(int x,int y){
    if(y == n-1)return triangle[x][y];
    int & ret = triangle[x][y];
    if(ret != -1)return ret;
    //可以这么理解,每一个小路径都是最大的,那么总的就是最大的
    return ret = max(path(x,y+1),path(x+1,y+1)) + triangle[x][y];
}

利用迭代动态规划求三角形的最大路径

int n,triangle[100][100];
int C[100][100];
int iterative(){
    for(int x =0;x<n;++x)
    C[n-1][x] = triangle[n-1][x];;
    
    for(int y = n-2;y>=0;--y)
    for(int x=0;x<y+1;++x)
    C[y][x] = max(C[y+1][x],C[y+1][x+1] + triangle[y][x]);
    return C[0][0];
}

三角形最大路径的个数

思路,对于下边如果大于右下角的,那么路径数就是下边的,反之则是右下角,但如果两者相同,那么就是一样的,两边都加。

int countCache[100][100];
int count(int x,int y){
    if(y == n-1)return 1;
    int & ret = countCache[x][y];
    if(ret != -1)
    return ret;
    ret = 0;
    if(path(x,y+1)>=path(x+1,y+1)) ret += countCache(x,y+1);
    if(path(x+1,y+1)>=path(x,y+1)) ret += countCache(x+1,y+1);
    return ret;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落春只在无意间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值