1. 动态规划如何去找动态转移方程
1、最长公共子串
假设两个字符串为str1和str2,它们的长度分别为n和m。d[i][j]表示str1中前i个字符与str2中前j个字符分别组成的两个前缀字符串的最长公共长度。这样就把长度为n的str1和长度为m的str2划分成长度为i和长度为j的子问题进行求解。状态转移方程如下:
dp[0][j] = 0; (0<=j<=m)
dp[i][0] = 0; (0<=i<=n)
dp[i][j] = dp[i-1][j-1] +1; (str1[i] == str2[j])
dp[i][j] = 0; (str1[i] != str2[j])
因为最长公共子串要求必须在原串中是连续的,所以一但某处出现不匹配的情况,此处的值就重置为0。
详细代码请看最长公共子串。
2、最长公共子序列
区分一下,最长公共子序列不同于最长公共子串,序列是保持子序列字符串的下标在str1和str2中的下标顺序是递增的,该字符串在原串中并不一定是连续的。同样的我们可以假设dp[i][j]表示为字符串str1的前i个字符和字符串str2的前j个字符的最长公共子序列的长度。状态转移方程如下:
dp[0][j] = 0; (0<=j<=m)
dp[i][0] = 0; (0<=i<=n)
dp[i][j] = dp[i-1][j-1] +1; (str1[i-1] == str2[j-1])
dp[i][j] = max{dp[i][j-1],dp[i-1][j]}; (str1[i-1] != str2[j-1])
详细代码请看最长公共子序列。
3、最长递增子序列(最长递减子序列)
因为两者的思路都是一样的,所以只给出最长递减子序列的状态转移方程。假设有序列{a1,a2,...,an},我们求其最长递增子序列长度。按照递推求解的思想,我们用F[i]代表若递增子序列以ai结束时它的最长长度。当 i 较小,我们容易直接得出其值,如 F[1] = 1。那么,如何由已经求得的 F[i]值推得后面的值呢?假设,F[1]到F[x-1]的值都已经确定,注意到,以ax 结尾的递增子序列,除了长度为1的情况,其它情况中,ax都是紧跟在一个由 ai(i < x)组成递增子序列之后。要求以ax结尾的最长递增子序列长度,我们依次比较 ax 与其之前所有的 ai(i < x), 若ai小于 ax,则说明ax可以跟在以ai结尾的递增子序列之后,形成一个新的递 增子序列。又因为以ai结尾的递增子序列最长长度已经求得,那么在这种情况下,由以 ai 结尾的最长递增子序列再加上 ax 得到的新的序列,其长度也可以确定,取所有这些长度的最大值,我们即能得到 F[x]的值。特殊的,当没有ai(i < x)小 于ax, 那么以 ax 结尾的递增子序列最长长度为1。 即F[x] = max{1,F[i]+1|ai<ax && i<x}。
详细代码请看最长递增子序列。
4、最大子序列和的问题
假设有序列{a1,a2,...,an},求子序列的和最大问题,我们用dp[i]表示以ai结尾的子序列的最大和。
dp[1] = a1; (a1>=0 && i == 1)
dp[i] = dp[i-1]+ai; (ai>=0 && i>=2)
dp[i] = 0; (dp[i-1] + ai <=0 && i>=2)
详细代码请看最大子序列的和。
5、数塔问题(动态搜索)
给定一个数组data[n][m]构成一个数塔求从最上面走到最低端经过的路径和最大。可以假设dp[i][j]表示走到第i行第j列位置处的最大值,那么可以推出状态转移方程:
dp[i][j] = max{dp[i-1][j-1],dp[i-1][j]} + data[i][j];
View Code
6、(01)背包问题
这是一个经典的动态规划问题,另外在贪心算法里也有背包问题,至于二者的区别在此就不做介绍了。
假设有N件物品和一个容量为V的背包。第i件物品的体积是v[i],价值是c[i],将哪些物品装入背包可使价值总和最大?
每一种物品都有两种可能即放入背包或者不放入背包。可以用dp[i][j]表示第i件物品放入容量为j的背包所得的最大价值,则状态转移方程可以推出如下:
dp[i][j]=max{dp[i-1][j-v[i]]+c[i],dp[i-1][j]};
View Code
可以参照动态规划 - 0-1背包问题的算法优化、动态规划-完全背包问题、动态规划-多重背包问题
7、矩阵连乘(矩阵链问题)-参考《算法导论》
例如矩阵链<A1,A2,A3>,它们的维数分别为10*100,100*5,5*50,那么如果顺序相乘即((A1A2)A3),共需10*100*5 + 10*5*50 = 7500次乘法,如果按照(A1(A2A3))顺序相乘,却需做100*5*50 + 10*100*50 = 75000次乘法。两者之间相差了10倍,所以说矩阵链的相乘顺序也决定了计算量的大小。
我们用利用动态规划的方式(dp[i][j]表示第i个矩阵至第j个矩阵这段的最优解,还有对于两个矩阵A(i,j)*B(j,k)则需要i*j*k次乘法),推出状态转移方程:
dp[i][j] = 0; (i ==j,表示只有一个矩阵,计算次数为0)
dp[i][j] = min{dp[i][k] + dp[k+1][j] + p[i-1]*p[k]*p[j]}; (i<j && i<=k<j)
dp[1][n]即为最终求解.
View Code
2. 为什么有人说弄懂了《算法导论》的90%,就超越了90%的程序员
其实计算机程序底层核心就是各种数学算法,剩下就是怎么用代码去实现数学,世界上有名的计算机程序大牛几乎都跟数学权威方面的专家有关。
从另一个角度回答,因为就算看懂百分百,也很难超越另外的百分之十
很多程序员没读过算法导论
其实不管是对于在校生来说还是已经工作的程序员,一般很少都会接触算法。
学生的话也只有计算机相关专业的开设了数据结构和算法相关课程的才需要用到,但如果只是对付期末考试的话也没啥难度。
但是如果在大学期间接触到算法竞赛就不一样了,需要花费比较多的精力。
的确在工资上任何公司都是10%的算法大佬拿的工资比其他90%的业务开发程序员或者其他的程序员都要高,不过就凭只懂《算法导论》这本书的话还是不太行的,算法离不开业务的。就算超越也是超越那10%的算法工程师里的90%,如果能达到这个境界别说BAT了,微软谷歌都是可以考虑的。
说这个话在我看来他可能是想卖课,卖完再慢慢告诉你,“学到90%也没有那么容易”,或者“在刷我这套题这件事上超越90%的程序员 并不等于收入上超越90%的程序员”。
你多去拼多多参加几个活动,在文字 游戏 和预期管理上你应该就懂了;要是还不懂,大概你也不是那么适合做这一行以及算法导论。
公式:弄懂+一本名着+百分比+超越+百分比+你的群体。
例句:
弄懂sicp的67.9%,你就超越了95%的程序员。
弄懂本草纲目的72%,你就超越了93.7%的中医。
弄懂冰箱说明书的83%,你就超越了99.9%的冰箱使用者(这也许是最真实的,虽然冰箱说明书不是名着……)
至于为什么这么说……个人觉得就是对xx东西的一种崇拜,很大程度上是人云亦云。
算法导论是本不会动的书,不同人读效果不一样的。不要神化某一本书,参差多态乃幸福本源。不看算法导论你也可以会算法,你也可以会数据结构,你也可以进大厂。没有算法导论的时候也依然有研究算法的科学家。你能通过他学会知识很好,但你觉得它晦涩,搞不懂,没有c的代码让你学的不舒服,那就不看他。
人生中见书,书中见人生。读书有时候不一定是为了学东西,可能更多的是一种享受。就像你没学看过csapp之前,通过各种课程,学了零零碎碎的知识。忽然有一天你看了csapp,你觉得好过瘾啊,好爽啊。你觉得你学习的第一天就看csapp能有这种效果吗?
好书不会变少只会变多,更何况帮到你的也未必需要是好书。也许一本书只是很普通的书,不严谨,还都是大白话,但未必就帮不到你。
学东西莫要搞崇拜。很多程序员学习的时候都不是通过算法导论这本书学的,可他们依然很杰出。
程序员来回答一下:
1.《算法导论》这本书理论来说90%程序员也没弄懂,所以你弄懂了就超过了90%。
2.其实程序员是一个大的行业,IT也是一个大的行业,门外人看着都是一群写程序的,修电脑的,更有人认为是装电脑系统的,你被别人交过去装过系统吗?
3.程序员架构上来说,嵌入式 协议栈 应用 网络 服务器 工具 系统 等等等!
4.有一些行业是不需要看算法导论的,更有一些转行过来的,应该更不太了解算法导论。
这本书在美国的大学被称为clrs, 是标准的本科高年级和研究生入门的算法课课本。优点是比较全面的讲解了常用和基本的算法,习题质量不错。问题是动态规划讲的不好,篇幅原因一些近代的算法没有概括。总的来说是本不错的算法入门教科书。
算法是计算机科学的核心。计算理论偏数学,编译原理和操作系统偏硬件,真正计算机科学的核心就是算法。无论做研究还是搞工程,都是必不可少的。
程序是给人看的,不是给机器。写给机器的程序谁都可以写出来,但不是每个程序员都能写出别人看懂的东西
程序是什么,程序就是数据结构和算法,弄懂了超90%的程序员不是很正常嘛
看懂2%就超过了80%,没必要看那么多
因为这本书翻译的很枯燥、也很理解,这种情况下你还理解了90%,说明你有耐心,有恒心,耐得住寂寞。我相信不只是做程序员,做其它行业也会很优秀。
3. 《算法导论》有什么好的学习心得
本人没有读过这本书,文化水平不够,就算读了估计也是不知所云,这个应该是比较专业的人看的吧,那我只能从网上摘录些供大家分享。
推荐每学一个算法,就去各个OJ(Online Judge)找一些相关题目做做,有时理论让人很无语,分析代码也是一个不错的选择。
4. java数据结构书籍推荐
1. 入门级
针对刚入门的同学,建议不要急着去看那些经典书,像《算法导论》、《算法》这些比较经典、权威的书。虽然书很好,但看起来很费劲,如果看不完,效果会很不好。所以建议先看两本入门级的趣味书:
《大话数据结构》
《算法图解》
大话数据结构
将理论讲的很有趣,不枯燥。作者结合生活中的例子去对每个数据结构和算法进行讲解,让人通俗易懂。
算法图解
这是一本像小说一样有趣的算法入门书,书中有大量的图解,通俗易懂。
看完上面一本或两本入门级的书,你就会对数据结构和算法有个大概认识和学习。但这些入门级的书缺少细节、不够系统。所以想要深入的学习数据结构和算法,光看这两本书肯定是不够的。
2. 不同语言的教科书
国内外很多大学都是将《数据结构和算法分析》作为教科书。这本书非常系统、严谨、全面,难度适中,很适合对数据结构和算法有些了解,并且已经掌握了至少一门语言的同学学习。针对不同的语言,分别有:
《数据结构与算法分析:C语言描述》
《数据结构与算法分析:C++描述》
《数据结构与算法分析:java语言描述》
如果你不会C、C++、java,会Python或者JavaScript,可以看:
《数据结构与算法JavaScript描述》
《数据结构与算法:Python语言描述》
3. 面试书籍
现在很多大厂的面试都会考算法题,这里推荐几本面试算法书籍:
《剑指offer》
《编程珠玑》
《编程之美》
剑指offer
为面试算法量身定做的一本书。几乎包含了所有常见的、经典的面试题,如果能搞懂书里面的内容,一般公司的算法面试都应该没问题。
编程珠玑
这本书豆瓣评分有9分,评分很高。这本书最大的特色是讲了很多海量数据的处理技巧。其他算法书籍很少涉及海量数据。
编程之美
有些作者是微软工程师,算法题目较难,比较适合要面试Google、Facebook这样的公司的人去看。
4. 经典书籍
现在数据结构与算法最经典的书籍就是:
《算法导论》
《算法》
《计算机程序设计艺术》
这三本书非常经典,但都很厚,看起来比较费劲,估计很少有人能全部看完。但如果想更深入地学一遍数据结构和算法,还是建议去看看。
算法导论
章节安排不是循序渐进,里面有各种算法正确性、复杂度的证明、推导,对数学功底有一定要求,看起来有些费劲。
算法
偏重讲算法。内容不够全面,对数据结构方面的知识讲的不多,动态规划这么重要的知识点却没有讲。
计算机程序设计艺术
这本书包括很多卷,相比于其他书籍有更好的深度、广度、系统性和全面性。但如果你对数据结构和算法不是特别感兴趣,没有很好的数学、算法、计算机基础,很难把这本书读完、读懂。
5. 课外阅读
有些算法书籍也比较适合在平时悠闲的时候翻翻看看:
《算法帝国》
《数学之美》
《算法之美》
这些书都列举了大量的列子来解释说明,非常通俗易懂。
5. 算法导论 第二版 第三版的区别
第三版比第二版去掉了几章,例如排序网络之类的冷门算法,加入了并行算法等热门的内容。
动态规划这一章做了些修改,论述的内容不变,就是选的例子更好一些。
另外第三版更新了一些习题和思考题,所以习题编号肯定有变化。说实话,思考题才是此书最精彩的地方,但是一般人看《算法导论》,能把前面的算法描述搞清楚就不错了,90%的读者会略过算法复杂度分析部分,而最后的每一章的思考题部分,99%的读者都不会去看的。
因为之前看过第二版的大部分,所以我第三版读起来没有太多障碍。
如果你能把思考题都解决了,你在简历上写个精通《算法导论》也是理直气壮的。
6. 动态规划 最长公共子序列 过程图解
首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。
这里给出一个例子:有两个母串
cnblogs
belong
比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与母串保持一致,我们将其称为公共子序列。最长公共子序列(Longest Common Subsequence,LCS),顾名思义,是指在所有的子序列中最长的那一个。
子串是要求更严格的一种子序列, 要求在母串中连续地出现 。
在上述例子的中,最长公共子序列为blog(cnblogs,belong),最长公共子串为lo(cnblogs, belong)。
给一个图再解释一下:
如上图,给定的字符序列: {a,b,c,d,e,f,g,h},它的子序列示例: {a,c,e,f} 即元素b,d,g,h被去掉后,保持原有的元素序列所得到的结果就是子序列。同理,{a,h},{c,d,e}等都是它的子序列。
它的子串示例:{c,d,e,f} 即连续元素c,d,e,f组成的串是给定序列的子串。同理,{a,b,c,d},{g,h}等都是它的子串。
这个问题说明白后,最长公共子序列(以下都简称LCS)就很好理解了。
给定序列s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2},s1和s2的相同子序列,且该子序列的长度最长,即是LCS。
s1和s2的其中一个最长公共子序列是 {3,4,6,7,8}
求解LCS问题,不能使用暴力搜索方法。 一个长度为n的序列拥有 2的n次方个子序列,它的时间复杂度是指数阶 ,太恐怖了。解决LCS问题,需要借助动态规划的思想。
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。 为了避免大量的重复计算,节省时间,我们引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,这就是动态规划法所采用的基本方法。
解决LCS问题,需要把原问题分解成若干个子问题,所以需要刻画LCS的特征。
设A=“a0,a1,…,am”,B=“b0,b1,…,bn”,且Z=“z0,z1,…,zk”为它们的最长公共子序列。不难证明有以下性质:
如果am=bn,则zk=am=bn,且“z0,z1,…,z(k-1)”是“a0,a1,…,a(m-1)”和“b0,b1,…,b(n-1)”的一个最长公共子序列;
如果am!=bn,则若zk!=am,蕴涵“z0,z1,…,zk”是“a0,a1,…,a(m-1)”和“b0,b1,…,bn”的一个最长公共子序列;
如果am!=bn,则若zk!=bn,蕴涵“z0,z1,…,zk”是“a0,a1,…,am”和“b0,b1,…,b(n-1)”的一个最长公共子序列。
有些同学,一看性质就容易晕菜,所以我给出一个图来让这些同学理解一下:
以我在第1小节举的例子(S1={1,3,4,5,6,7,7,8}和S2={3,5,7,4,8,6,7,8,2}),并结合上图来说:
假如S1的最后一个元素 与 S2的最后一个元素相等,那么S1和S2的LCS就等于 {S1减去最后一个元素} 与 {S2减去最后一个元素} 的 LCS 再加上 S1和S2相等的最后一个元素。
假如S1的最后一个元素 与 S2的最后一个元素不等(本例子就是属于这种情况),那么S1和S2的LCS就等于 : {S1减去最后一个元素} 与 S2 的LCS, {S2减去最后一个元素} 与 S1 的LCS 中的最大的那个序列。
假设Z=<z1,z2,⋯,zk>是X与Y的LCS, 我们观察到
如果Xm=Yn,则Zk=Xm=Yn,有Zk−1是Xm−1与Yn−1的LCS;
如果Xm≠Yn,则Zk是Xm与Yn−1的LCS,或者是Xm−1与Yn的LCS。
因此,求解LCS的问题则变成递归求解的两个子问题。但是,上述的递归求解的办法中, 重复的子问题多,效率低下。改进的办法——用空间换时间,用数组保存中间状态,方便后面的计算。这就是动态规划(DP)的核心思想了。
DP求解LCS
用二维数组c[i][j]记录串x1x2⋯xi与y1y2⋯yj的LCS长度,则可得到状态转移方程
以s1={1,3,4,5,6,7,7,8},s2={3,5,7,4,8,6,7,8,2}为例。我们借用《算法导论》中的推导图:
图中的空白格子需要填上相应的数字(这个数字就是c[i,j]的定义,记录的LCS的长度值)。填的规则依据递归公式,简单来说:如果横竖(i,j)对应的两个元素相等,该格子的值 = c[i-1,j-1] + 1。如果不等,取c[i-1,j] 和 c[i,j-1]的最大值。首先初始化该表:
S1的元素3 与 S2的元素5 不等,c[2,2] =max(c[1,2],c[2,1]),图中c[1,2] 和 c[2,1] 背景色为浅黄色。
继续填充:
至此,该表填完。根据性质,c[8,9] = S1 和 S2 的 LCS的长度,即为5。
本文S1和S2的最LCS并不是只有1个,本文并不是着重讲输出两个序列的所有LCS,只是介绍如何通过上表,输出其中一个LCS。
我们根据递归公式构建了上表,我们将从最后一个元素c[8][9]倒推出S1和S2的LCS。
c[8][9] = 5,且S1[8] != S2[9],所以倒推回去,c[8][9]的值来源于c[8][8]的值(因为c[8][8] > c[7][9])。
c[8][8] = 5, 且S1[8] = S2[8], 所以倒推回去,c[8][8]的值来源于 c[7][7]。
以此类推,如果遇到S1[i] != S2[j] ,且c[i-1][j] = c[i][j-1] 这种存在分支的情况,这里请都选择一个方向(之后遇到这样的情况,也选择相同的方向)。
这就是倒推回去的路径,棕色方格为相等元素,即LCS = {3,4,6,7,8},这是其中一个结果。
如果如果遇到S1[i] != S2[j] ,且c[i-1][j] = c[i][j-1] 这种存在分支的情况,选择另一个方向,会得到另一个结果。
即LCS ={3,5,7,7,8}。
构建c[i][j]表需要Θ(mn),输出1个LCS的序列需要Θ(m+n)。
参考:
https://blog.csdn.net/hrn1216/article/details/51534607
https://blog.csdn.net/u012102306/article/details/53184446
7. 计算机科学的“两本圣经”是什么
第一本:《算法导论》原书名——《Introction to Algorithms》,
第二本:高德纳(Donald E.Knuth)的《计算机程序设计艺术》(《The Art Of Computer Programming》)
计算机科学是一门包含各种各样与计算和信息处理相关主题的系统学科,从抽象的算法分析、形式化语法等等,到更具体的主题如编程语言、程序设计、软件和硬件等。计算机科学分为理论计算机科学和实验计算机科学两个部分。
(7)算法导论动态规划扩展阅读:
研究课题
①、计算机程序能做什么和不能做什么(可计算性);
②、如何使程序更高效的执行特定任务(算法和复杂性理论);
③、程序如何存取不同类型的数据(数据结构和数据库);
④、程序如何显得更具有智能(人工智能);
⑤、人类如何与程序沟通(人机互动和人机界面)。
相关奖项
计算机科学领域的最高荣誉是ACM设立的图灵奖,被誉为是计算机科学的诺贝尔奖。它的获得者都是本领域最为出色的科学家和先驱。华人中首获图灵奖的是姚期智先生.他于2000年以其对计算理论做出的诸多“根本性的、意义重大的”贡献而获得这一崇高荣誉。
专业介绍
培养目标
本专业培养德、智、体全面发展,具有计算机应用技术的基础理论知识,具备计算机及相关设备的维护与维修、行业应用软件、平面图像处理、广告设计制作、动画制作、计算机网络及网站建设与管理、数据库管理与维护等应用能力和操作能力的高等技术应用性人才。
计算机应用基础、计算机组装与维护、计算机局域网络的建设与管理、网络工程、操作系统、服务器、数据库的开发与应用、网站建设与网页设计、C/C++语言、Visual Basic语言、平面设计、3D图形设计、多媒体设计、专业英语。
就业方向
毕业生主要面向交通系统各单位、交通信息化与电子政务建设与应用部门、各类计算机专业化公司、广告设计制作公司、汽车营销技术服务等从事IT行业工作。
参考资料:网络-计算机科学
8. 计算机科学的“两本圣经”是什么
科曼的《算法导论》和高德纳的《计算机程序设计艺术》被称为计算机科学的两本经典着作,被业界戏称为“两本圣经”
科曼的《算法导论》这本书深入浅出,全面地介绍了计算机算法。对每一个算法的分析既易于理解又十分有趣,并保持了数学严谨性。涵盖的内容有:算法在计算中的作用,概率分析和随机算法的介绍。
《算法导论》书中专门讨论了线性规划,介绍了动态规划的两个应用,随机化和线性规划技术的近似算法等,还有有关递归求解、快速排序中用到的划分方法与期望线性时间顺序统计算法,以及对贪心算法元素的讨论。
高德纳的《计算机程序设计艺术》这本书结合大量数学知识,分析不同应用领域中的各种算法,研究算法的复杂性,即算法的时间、空间效率,探讨各种适用算法等,其理论和实践价值得到了全世界计算机工作者的公认。
(8)算法导论动态规划扩展阅读
《算法导论》自第一版出版以来,已经成为世界范围内广泛使用的大学教材和专业人员的标准参考手册。本书全面论述了算法的内容,从一定深度上涵盖了算法的诸多方面,同时其讲授和分析方法又兼顾了各个层次读者的接受能力。
《算法导论》所有算法都是用英文和伪码描述,使具备初步编程经验的人也可读懂。全书讲解通俗易懂,且不失深度和数学上的严谨性。第二版增加了新的章节,如算法作用、概率分析与随机算法、线性编程等,几乎对第一版的各个部分都作了大量修订。
《计算机程序设计艺术》书中引入的许多术语、得到的许多结论都变成了计算机领域的标准术语和被广泛引用的结果。另外,作者对有关领域的科学发展史也有深入研究,因此本书介绍众多研究成果的同时,也对其历史渊源和发展过程做了很好的介绍,这种特色在全球科学着作中是不多见的。
参考资料网络--计算机科学
网络--计算机程序设计艺术
网络--算法导论
9. 算法导论的内容简介
《算法导论》自第一版出版以来,已经成为世界范围内广泛使用的大学教材和专业人员的标准参考手册。本书全面论述了算法的内容,从一定深度上涵盖了算法的诸多方面,同时其讲授和分析方法又兼顾了各个层次读者的接受能力。各章内容自成体系,可作为独立单元学习。所有算法都用英文和伪码描述,使具备初步编程经验的人也可读懂。全书讲解通俗易懂,且不失深度和数学上的严谨性。第二版增加了新的章节,如算法作用、概率分析与随机算法、线性编程等,几乎对第一版的各个部分都作了大量修订。
本书深入浅出,全面地介绍了计算机算法。对每一个算法的分析既易于理解又十分有趣,并保持了数学严谨性。本书的设计目标全面,适用于多种用途。涵盖的内容有:算法在计算中的作用,概率分析和随机算法的介绍。本书专门讨论了线性规划,介绍了动态规划的两个应用,随机化和线性规划技术的近似算法等,还有有关递归求解、快速排序中用到的划分方法与期望线性时间顺序统计算法,以及对贪心算法元素的讨论。本书还介绍了对强连通子图算法正确性的证明,对哈密顿回路和子集求和问题的NP完全性的证明等内容。全书提供了900多个练习题和思考题以及叙述较为详细的实例研究。
本书内容丰富,对本科生的数据结构课程和研究生的算法课程都是很实用的教材。本书在读者的职业生涯中,也是一本案头的数学参考书或工程实践手册。
10. 为什么算法导论中的数组序号是从1开始的
c语言下标从零开始是个错误,并且 index 也是一个有误导性的名词,它表示的是偏移量,明明应该用 offset。
然后 c 的徒子徒孙都学了它,导致现在很多人都误以为下标应该从 0 开始。
早期蛮荒时代,很多东西都不科学,算法导论作者致力于与落后文明作斗争,然而却遭到了楼主你的不理解,实乃编程届一大憾事。
我再说一遍,C 是结构化的汇编,下标基 0 是受到了 PDP-11 指令集的影响,更老的语言(比如 Fortran)都是基 1 的。
另外用 0/非 0 代表 false/true 也是 PDP-11 中 TST 指令和 Z 位的行为。
可能是这本书强调算法的求学思想,所以从一更加符合数学的数组规定。
但是编程的时候,指针这个东西会经常用到,如果用a(o)作为第一个元素 那么*a+n就等同于a(n) 比较方便
算法导论上的这个问题呢,我觉得我比较同意楼上的看法,这个书上面的很多的程序并不是可以敲上去直接运行的,他只是伪代码,思想而已,给人看的,人类的普遍思维是从1开始,那么书页就是从1开始了
说编程语言是给机器看而伪代码是给人看的简直是逗大家笑吧...编程语言设计出来就是给人看的....
另外从0开始在很多方便都极好....我觉得写多代码都能体会到吧..
帮算导洗地:
算法导论通篇用的是伪代码 是给人类阅读理解的 不是设计给机器去运行的
而绝大多数情况下, index 从 1 开始更符合人类直觉(如果你对这点有异议请参考的答案 )
但少数情况下, index 从 0 开始更符合人类直觉。例如书中 hashing 还有 FFT 那块内容, index 是从 0 开始的。
其实写几天 Pascal 你就适应啦。。