我所感受到的数学之美(荐书)
很久之前就听说过吴军博士《数学之美》的大名,但迟迟未读。
什么原因呢?
一提到数学,我脑袋中不免出现“微积分、泰勒公式、无穷级数”等令人无比头痛的概念。它似乎是居学堂之高,离实际之远。
然而前不久读完,真真儿有醍醐灌顶、耳目一新之感。
在《数学之美》中,吴博士将数学原理讲的通俗易懂,并通过实际的例子展示了数学的超级能力。
如书中提到的一系列复杂的计算机问题(分词、语音识别、机器翻译等),都被科学家们用数学知识轻松解决。作为非专业人士(我)也看的是津津有味。
我由衷的钦佩那些为人类做出伟大贡献的计算机科学家们,更被数学的强大威力而震撼。
同时不得不为自己的浅薄无知而感到无比羞愧。
作为平凡人,是否就不能亲身感受到数学之美么?我这样想。
直到某天,看到一道算法题——打家劫舍:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
这是一道关于动态规划的题,熟悉的同学可能很快就知道解法,但我在分析过程中切切实实感受到了一把数学之美。分享一下。
【分析】
动态规划的三个特征:
- 求最优解
- 具有重复子问题,且子问题还有重叠的更小的子问题
- 整体问题最优解取决于子问题的最优解
我们知道,解决动态规划问题的关键,就是【找规律】。
根据动态规划类问题的特征,得到每个子问题的最优解,那么最终的结果就是最优的。
解题的一般思路为:
- 1、假设存在最优解且结果已知;
- 2、根据题意从后往前推,找规律/通项,也即整体问题和子问题之间的关系。
就本题而言,可以把问题抽象为:给定一组非负整数,在相邻两项不能相加的前提下,求最大和。
-
第一步:我们不妨假设第n、n-1、n-2、...项对应的最优结果存在且确定。
-
第二步:根据题意,第 n 项对应的结果 = max(第 n 项的值 + 第 n-2 项对应的结果,第 n-1 项对应的结果)
用数学公式写出通项:
f(n) = max(n + f(n-2), f(n-1)). 其中n = 1,2,3... (*)
这里,我们可以用初中知识【数学归纳/演绎】来验证通项(*)的正确性。
假设给定的数据为:x1,x2,x3...,xn。其中1,2,3...,n表示下标
f(1) = max(x1 + f(-1), f(0)) = x1 ------------f(1)结果最优
f(2) = max(x2 + f(0), f(1)) = max(x2, x1) ----f(2)结果最优
f(3) = max(x3 + f(1), f(2)) ------------------f(3)结果最优
...
推证过程从后往前,是假设已知结论求通项,是为找到解题关键。
但实现过程应从前往后,子问题有了最优解,整体问题解才最优。
于是,写代码便成了一件相对容易的事:
int robMax (vector<int> nums) {
if (nums.empty()) return 0;
int last = nums[0];
int current = max(last, nums[1]);
for (int i = 2; i < nums.size(); ++i) {
int temp = last;
last = current;
current = max(nums[i] + last, current);
}
return current;
}
算法问题最终都是数学问题——Hen·BioNian
抛砖引玉也好,班门弄斧也罢,其实都是为了安利《数学之美》这本小书。
还记得余弦定理、线性代数吗?你是否也认为它除了能算夹角、解线性方程外并没有实际的用处?《数学之美》会给你答案。
当然,我举的小小例子远不如书中讲的深刻、精彩。莫见怪莫见怪。
完)