六月中旬了,马上就要期末考试了,期末考试结束以后就要迎来紧张刺激的留校集训,到那时博客会更新的比较频繁,而现在在准备期末考试,所以可能更新的博客稍微少一些。

话不多说,今天来更一篇刚刚吃饭的时候关于记忆化搜索和动态规划的一些区别的思考。

记忆化搜索(Memory Search),其实还是用递归函数实现的,通常函数名依然叫做dfs(  ̄□ ̄||)。核心语句就是那两部分关键的语句块啦。

1.函数一开始的判断出口:if(搜索过) return 数组中的值。因为这里涉及到是否搜索过,所以一般将数组初始化为-1,详情见那道经典的滑雪题目:链接稍后送上。那道滑雪题,也可以用dp解,他俩的区别和解题的不同一会博客中也会有提到。

2.函数的递归前进语句:return fib[i]=fib[i-1]+fib[i-2];(没有具体的例子实在不好说了,所以这里用fib数列来做演示)。

这样就做到了数组的每个值只计算了一次,不会有多余的时间消耗。

还有一点!记住ms型dfs就必须是int型的了!! 不要在用bool或者void了!

下面送上记忆化搜索的fib求解的部分代码:

#include<iostream>
using namespace std;
const int MAX = 10000+5;
int fib[MAX];
int dfs(int n) {// if(fib[n]!=-1) return fib[n];return fib[n]=dfs(n-1)+dfs(n-2);}
int main()
{fib[1]=fib[2]=1;for(int i = 2; i<MAX; i++) {fib[i]=-1;}dfs(MAX-1);//别写成了MAX,那样输出的全是-1 for(int i = 1; i<=50; i++) {printf("%d ",fib[i]);if(i%5==0) { printf("\n"); }}return 0 ;} 

输出结果:

1 1 2 3 5
8 13 21 34 55
89 144 233 377 610
987 1597 2584 4181 6765
10946 17711 28657 46368 75025
121393 196418 317811 514229 832040
1346269 2178309 3524578 5702887 9227465
14930352 24157817 39088169 63245986 102334155
165580141 267914296 433494437 701408733 1134903170
1836311903 -1323752223 512559680 -811192543 -298632863

从中也容易看出来,fib数列增长还是很快的!(通项可以用母函数表示出来!但是目前对母函数尚未学精,暂不做讨论)

下面是一个很值特研究的问题:

为什么说能用dp的都能用ms,但是反之不立。(至少我是这么认为的)

在fib中,你会发现写记忆化搜索像个傻子一样自取麻烦,直接dp递推多简单,多此一举。但之所以在fib中ms和dp如此相似是因为fib的顺序是固定的!有规律的!所以体现不出ms的用处来!

再看一道题比如滑雪,你如果用dp,必须要排序!然后按照排序的顺序(那道题是按照高度排序的)从小到大递推!原因也很简单,因为dp[i][j]可能需要用到四周的值!且dp有个特点,我既然要用你,那么你的值,比如要是已经确定的值(就是不会再更新这个值了),我给他取个名叫完成值,并给他一个特点,那就是,你如果是完成值,那么你将不会再被更新了,也就是,对这个数据,只有读的功能,没有写的功能。也就是说,比如if(i,j右边那个点的高度(即i,j+1)<当前i,j坐标的高度),那么更新dp[i][j],并且dp[i][j]也是完成值了!(通过判断是不是-1来确定是否是完成值,因为最开始初始化成-1),而如果i,j右边那个点的高度(即i,j+1)<当前i,j坐标的高度,那就无所谓i,j+1是不是完成值了,,,反正你也不去读这个数据(刚刚说过了对完成值只能读不能写!)所以你需要用到的值,都是高度比你小的值,这也是为什么需要进行按照高度从小到大进行排序,并且递推的时候,只能按照这个顺序进行递推!

上面一段是你如果用dp的情况,而如果你用的是ms,情况将没这么复杂,不需要排序!不需要按照一定顺序递推!而只需要上面提到的两条关键的语句块,就解决的所有事情!具体还是需要自己体会的。、。。

下面贴上滑雪的ms代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;int r,c;
int maze[105][105];
int dp[105][105];
void init () {for(int i = 1; i<=104 ; i++) {for(int j = 1 ; j<=104 ; j++) {dp[i][j]=-1;}}
}
bool ok(int x,int y){if(x<=r&&x>0&&y<=c&&y>0) return true;else return false;
}
int dfs(int x,int y) {if(dp[x][y]!=-1) {return dp[x][y];}
//  if(x==0||y==0) return 0 ;int flag=0;int next[4]={0,0,0,0};if(maze[x+1][y]<maze[x][y]&&ok(x+1,y)) {next[0]=dfs(x+1,y);flag=1;}if(maze[x][y+1]<maze[x][y]&&ok(x,y+1)) {next[1]=dfs(x,y+1);flag=1;}if(maze[x-1][y]<maze[x][y]&&ok(x-1,y)) {next[2]=dfs(x-1,y);flag=1;}if(maze[x][y-1]<maze[x][y]&&ok(x,y-1)) {next[3]=dfs(x,y-1);flag=1;}if(flag==0) return dp[x][y]=0;return dp[x][y]=1+*max_element(next,next+4);
}
int main()
{cin >> r>>c;int maxx=0;init();for(int i=1; i<=r; i++) {for(int j = 1 ; j<=c ; j++) {scanf("%d",&maze[i][j]);}}for(int i=1; i <= r ; i++) {for(int j = 1 ; j <= c ; j++) {maxx=max(maxx,dfs(i,j));}}cout << maxx+1<<endl;return 0 ;} 

对记忆化搜索(ms)和动态规划(dp)的深入理解相关推荐

  1. 【蓝桥杯】历届试题 地宫取宝(记忆化搜索、dfs、dp)

    历届试题 地宫取宝 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明被带到地宫的入口,国王要求他只能 ...

  2. 数位dp 记忆化搜索java_hdu 5787 数位dp,记忆化搜索

    题意:求区间[l,r]内有多少个数符合,这个数的任意的相邻k位数(digits),这k个数都两两不相等 l,r范围是1~1e18,k是2~5 思路:数位DP,因为K<=5,我们最多需要保存下来当 ...

  3. 【记忆化搜索】【线性化DP】滑雪 (ssl 1202/luogu 1434/pku 1088)

    滑雪滑雪滑雪 ssl 1202 luogu 1434 pku 1088 题目大意: 有一个N*M的矩阵,每个位置都有一个数,可以从大的数走向小的数,问可走的路最长是多少 原题 Michael喜欢滑雪百 ...

  4. UVa 1252 - Twenty Questions(记忆化搜索,状态压缩dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:点击打开链接 题目大意 有n个长度为m的二进制串,每个都是不同的. 为了把所有字符串区分开,你可以询问,每次可 ...

  5. 专题7:动态规划 记忆化搜索

    1. 什么是动态规划 ? 这是算法导论对动态规划的定义: 动态规划( dynamic programming,常简称为 dp ) 与分治方法相似,都是通过组合子问题的解来求解原问题( 在这里,&quo ...

  6. 动态规划+深度优先搜索+记忆化搜索(干货满满)

    动态规划的定义 动态规划算法与分治法的思想类似,都是通过组合子问题的解来求原问题.我先来给大家介绍一下分治思想,分治思想就是把一个复杂的问题,分解为k个规模相同的子问题,如果还是无法解决,子问题又可以 ...

  7. 动态规划5:动态规划与记忆化搜索

    本期题目: 单词拆分 单词拆分II 大礼包 记忆化搜索与狭义的动态规划 前面我们讲的动态规划很广义的思想,从起始时刻到终止时刻,每一步都要按照最优原则走,按照这个原则会产生一个迭代式,称为动态规划迭代 ...

  8. 博弈论(2)DP/记忆化搜索

    博弈问题的话,假设两个人都极度聪明,都会采取最优策略,那么就是也知道了对方也和自己一样聪明,我采取最优策略后,对方也会根据当前状态做出最优策略,简而言之,就是每个玩家都从第一步棋看到了最后一步棋. 先 ...

  9. UVA10739 String to Palindrome【记忆化搜索+DP】

    In this problem you are asked to convert a string into a palindrome with minimum number of operation ...

  10. 【牛客练习赛13】 A B C D【康拓展开】 E【DP or 记忆化搜索】 F 【思维】

    A 幸运数字Ⅰ 链接:https://www.nowcoder.com/acm/contest/70/A 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K, ...

最新文章

  1. spring boot初学习的数据库依赖
  2. USACO 1.3... 虫洞 解题报告(搜索+强大剪枝+模拟)
  3. windows2008 R2 如何建立FTP站点
  4. sql开启mysql远程连接_CentOS系统中安装MySQL和开启MySQL远程访问的方法
  5. 蓝桥杯 2011年第二届C语言初赛试题(3)
  6. 大型网站的Google排名策略
  7. maven 连接sqlserver
  8. 递归算法的总结与应用
  9. NUC1131 Triangle【DP】
  10. JAVA-数据库之MySQL与JDBC驱动下载与安装
  11. idea格式化代码时,方法顺序错乱问题
  12. 使用JOPENS-MSDP系统进行简单的地震定位
  13. iPhone 开发常用工具
  14. 【VUE】前端搜索引擎优化seo
  15. SQL Server数据分析面试题(202008)
  16. 微信公众平台开发教程之新手初级入门攻略 附PHP代码实例
  17. PyTorch grad 与 Optimizer(params) 区别
  18. HTML+JS 前端雪花飘落
  19. 自由人NFT元农(Meta Agriculture)发行计划
  20. 可微和可导的关系,全微分、偏微分、偏导数

热门文章

  1. mysql时间条件查询
  2. TCC88XX环境的搭建教程
  3. vue简易楼层跳跃(vue-scrollto)
  4. 1075: 聚餐人数统计 C语言
  5. 《用Python解决寻找水仙花数,百钱百鸡问题|CSDN创作打卡》
  6. 兆比特每秒和兆字节每秒_网速中的“KB”“MB”“s”等字母都是啥意思,读啥,比如兆这样?...
  7. 英语四级关于计算机阅读理解,英语四级阅读理解技巧大全!一看就会
  8. 【中土世界】精灵的主要分支
  9. 解决idea控制台乱码
  10. HTML table行距的改变方法