小杰想用存钱罐买一本价值15元的漫画书,他每天可以投入1元或3元。那么,存够15元一共有多少种不同的投币方案呢?这个看似简单的存钱问题,其实藏着信息学奥赛中最重要算法------动态规划的奥秘。
一、什么是动态规划?从存钱罐说起
想象一下,你的面前有一个神奇的存钱罐。这个存钱罐有点特别:它记得住 你每次存够不同金额时用了多少种方法,并且会用这些经验帮你更快算出新金额的存钱方法数。
这就是动态规划(Dynamic Programming,简称DP)的核心思想:
不要重复计算!
把已经知道的结果记下来,
直接用它们推导出新问题的答案。
是不是有点像我们学数学时用的"乘法口诀表"?背下口诀后,就不用每次都重新数手指了!
二、第一个DP问题:爬楼梯的奥秘
让我们从一个经典的DP入门题开始,它被称为"爬楼梯问题":
小明要爬上一座10级的楼梯,他一次可以走1级 ,也可以跨2级。请问,他有多少种不同的方法爬到楼顶?
🧠 跟着我这样想,保证你不迷糊!
第1步:从最简单的情况开始
我们先不想10级那么复杂,想想最少的几级:
-
第1级:只有1种方法(直接走1级上去)
-
第2级:有2种方法
-
方法①:走1级,再走1级
-
方法②:直接跨2级
-
第2步:准备"记忆笔记本"
我们把已经知道的结果记下来,这就是DP中的"状态":
text
到第1级:1种方法 → 记作 dp[1] = 1
到第2级:2种方法 → 记作 dp[2] = 2
第3步:找出"搭积木"的规律
现在想想第3级,小明怎么到达这里呢?
只可能从两个地方过来:
-
从第1级跨2级上来
-
从第2级走1级上来
所以,到第3级的方法数 = 到第1级的方法数 + 到第2级的方法数
用我们的"记忆笔记本"来说就是:dp[3] = dp[1] + dp[2] = 1 + 2 = 3
看明白了吗?我们没有从头开始想 ,而是用已经算好的答案拼出了新答案!
📊 动手画"魔法表格"
让我们把这种规律继续下去,画出一个神奇的表格:
| 台阶级数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 方法数 | 1 | 2 | 3 | 5 | 8 | 13 | 21 | 34 | 55 | 89 |
找规律时间:你发现这个数列的秘密了吗?
没错!这就是著名的斐波那契数列 !每个数都是前两个数的和。我们刚刚用动态规划重新发现了这个伟大的数列!
三、动态规划"三步口诀"
解决任何DP问题,都可以用下面这个万能口诀:
1. 定状态(准备笔记本)
问:我要记住什么?
→ 比如:
dp[i]表示爬到第i级台阶的方法数2. 找关系(发现拼图规律)
问:当前答案怎么用旧答案拼出来?
→ 比如:
dp[i] = dp[i-1] + dp[i-2]3. 从小算大(从简单开始填)
问:最小、最简单的答案是什么?
→ 比如:
dp[1]=1, dp[2]=2,然后一步一步算到dp[10]
四、挑战升级:网格中的"金币大冒险"
理解了基本思想后,我们来玩一个更刺激的游戏:
有一个3×3的网格迷宫,每个格子里放着不同数量的金币。机器人小R从左上角出发,每次只能向右 或向下移动一格,直到右下角。它最多能收集多少金币?
假设迷宫是这样的:
text
1 3 1
2 5 1
4 2 1
🎮 用"三步口诀"解决它!
第1步:定状态
dp[i][j] 表示从起点走到第i行第j列这个位置时,最多已经收集到的金币数。
第2步:找关系
机器人怎么到达(i, j)这个位置呢?只有两种可能:
-
从上面
(i-1, j)下来 -
从左边
(i, j-1)过来
机器人当然会选择金币更多的路径!所以:
dp[i][j] = 当前格子金币 + max(上面的dp[i-1][j], 左边的dp[i][j-1])
第3步:从小算大(填表格)
我们来一步步填这个表格(括号内表示从哪个方向来):
| 第0列 | 第1列 | 第2列 | |
|---|---|---|---|
| 第0行 | 1(起点) | 4(从左) | 5(从左) |
| 第1行 | 3(从上) | 9(从左:1+3+5) | 10(从上:9+1) |
| 第2行 | 7(从上) | 11(从上:7+2) | 12(从左:11+1) |
最终,机器人最多能收集12个金币!最优路径是:右→右→下→下。
五、动态规划在信息学奥赛中有多重要?
告诉你一个小秘密:在CSP-J/S、NOIP等信息学奥赛中,动态规划是每年必考的题型,而且经常出现在压轴题中!
为什么它这么重要?因为DP能解决许多看似复杂的实际问题:
-
背包问题:如何用有限的背包容量装下最有价值的物品?
-
最长公共子序列:两个DNA序列有多少相似部分?
-
最短编辑距离:把一个单词变成另一个单词最少需要多少步?
掌握了动态规划,你就拿到了打开信息学奥赛高分大门的金钥匙!
💎 想系统攻克动态规划?
如果你觉得这个入门指南有帮助,想更深入地学习动态规划的所有经典模型 ,我在CSDN的付费专栏《信息学奥赛算法通关宝典:从CSP-J到NOIP 》中,专门用5个章节详细讲解了:
背包问题的9大变种(01背包、完全背包、多重背包等)
区间DP的破解技巧(石子合并、括号匹配等问题)
树形DP的思维方法(树上最优选择问题)
状态压缩DP的实战应用
近3年CSP-J/S动态规划真题的逐题精讲
专栏不仅包含详细的文字解析,还有动画演示 和可运行的代码模板,适合想要在竞赛中取得突破的同学。点击这里了解详情。
六、DP思维在生活中大有用处
动态规划不只是竞赛算法,更是一种强大的思维方式:
-
零花钱规划:这周怎么花钱,才能既买零食又能攒钱买下个月的游戏卡?
-
作业安排:每天做多少作业,才能保证周末不用熬夜赶工?
-
游戏策略:先升级哪个技能,才能最快打败终极大Boss?
学会这种"记住经验、逐步优化"的思考方式,你会发现自己解决问题的能力大大提升了!
七、动手挑战:硬币凑金额
现在,请你用今天学到的"三步口诀",试着解决下面这个问题:
你有无限多的1元、3元和5元硬币。要凑出9元钱 ,最少需要多少枚硬币?
把你的思考过程和答案写在评论区吧!前10名回答正确的小伙伴,我会送你一份《动态规划经典例题集》电子版哦!
提示:想一想,要凑出9元,可以从哪些金额"一步到位"?记住我们的核心思想:用已经知道的结果推导新的结果!
八、总结:动态规划其实很简单
让我们再回顾一下动态规划的精髓:
-
分而治之:把大问题分解成小问题
-
记住结果:把已经解决的小问题答案存起来
-
避免重复:直接用已有答案,不要重复计算
只要掌握了这个"记事本+搭积木"的思想,你就能解决许许多多看似复杂的问题。
给小朋友的鼓励:不要被算法的名字吓到。动态规划就像学骑自行车,一开始可能会摇摇晃晃,但一旦掌握了平衡,你就会骑得飞快!多练习、多思考,你一定能成为DP小高手!
📌 专栏推荐 :如果你已经理解了动态规划的基础,想要在信息学奥赛中系统性地学习所有必考算法 ,欢迎关注我的专栏《信息学奥赛CSP-J/NOIP普及组题目》。