b97902HW 板


LINE

虽然强者森林已经发文了,不过看到递回还是颇为手痒啊。 毕竟小时候相当喜欢递回,当然现在也是。 ---- 前情提要结束 ---- 递回,便是将原问题,切成相同但规模较小的问题,一一解决後便知原问题的答案了。 至於如何去解决,便是靠规模够小、无法再分割时的答案,而这也是我们已知的。 而函数呢,看它是什麽型态,便可以将其视为该型态的一个数值, 其数值则视传入参数与运算方式等等而定。 举个老例子,计算 n! 为何。 已知 n! = (n-1)! * n,因此我们只要知道 (n-1)!,就可以知道 n! 的答案。 假设 f(i) 可以正确求出 i! 的值,於是在计算 n! 时, 只要先用 f() 计算 (n-1)! 的值,再将其乘上 n,即为所求。 这时会将切割後的子问题 (n-1)! 当作一个相同,但规模较小的独立问题来做。 而这个独立问题,设 m = n-1,则等同於求 f(m),即 m! 的值。 这又会求 (m-1)! 的答案,以算出 m!,所以变成了一样的问题。 但是前面只是假设正确,它真的正确吗? 已知 0! = 1,而若 i! 正确,(i+1)! = i! * (i+1) 也会是正确的, 所以这样写是正确的。 而实际程式在执行时,流程是这样子的: 假设我们呼叫了…不要太大,f(4) 就好。还和某首 debug 神歌有异曲同工之妙。 /* 以下 code 省略一些不太重要的东西 */ main() { printf("%d\n", f(4)); } 可是要输出之前,必须先算出 f(4) 的值为何。因此,main() 会呼叫 f(4), 并等待其算完,否则无法继续下去。 f(n) { if(n == 0) return 1; return f(n-1) * n; } 现在要计算 f(4),而 main() 正在等待结果。 想像你正在对抗强大的使徒,却孤立无援,只好求助於平日好朋友 f(4)。 这里你可能会质疑我,说不定强者我同学就会了,那干嘛继续递回下去? 想像你的朋友会解你问题的大部份,却有一些小地方不懂得怎麽解; 於是他再去问他朋友他不懂的地方,而他朋友在他不懂的地方也有一些不会解, 只好再去问朋友,… 将这些朋友依序由大到小编号 4~0 好了。 直到问到最後一个人 0,他成功把所有小疑问解答出来了, 则 1 问到这些小细节後,他也把 2 所提的问题全解答出来了。 2 问到他所不会的小地方後,也把 3 问他的全解出来了。 在 3 告诉了 4 怎麽解 4 卡住的地方後,4 也成功解出你所不会的地方; 於是你就 AC 啦! 运行过程如下: f(4) <== 现在在这里想办法求 f(4) main() /* 想像它们叠起来了,而我们得从最上面慢慢处理 */ /* 想像你是 main(),正等着 f(4) 解出你的问题,并告诉你。 */ 但我们不知道 4!,幸好我们知道可以先求 3!。 想像 4 在你提问的问题中,有一些不会解,只好问 3。 於是变成这样: f(3) <== 现在在这里 f(4) <== 等待 f(3) main() <== 等待 f(4) 可是 3 也必须求助於 2 才行,所以只好… f(2) <== 现在在这里 f(3) f(4) main() 可是 2 也还不知道呢…不拖戏,直接继续: f(1) <== 现在在这里 f(2) f(3) f(4) main() 於是求助於 1 f(0) <== 现在在这里 f(1) f(2) f(3) f(4) main() f(0) 终於所有问题都会,而不用再去问其它朋友啦! 於是 f(0) 将答案告诉 f(1),而 f(0) 的答案是 1。 f(1) <== f(0) 告诉他卡住的地方怎麽解後,就秒杀了,再告诉 f(2) f(2) f(3) f(4) main() 当 f(1) 告诉 f(2) 怎麽解 f(2) 所卡住的部份後,也就完全解决了 f(3) 的问题。 f(2) <== 在这里解决後,告诉 f(3) f(3) f(4) main() 接着换 f(3) 问到卡住的地方後,解决了 f(4) 的问题了。 f(3) <== 也解决了,告诉 f(4)。 f(4) main() f(4) 在问过 f(3) 他卡住的一小部份後,也把你发问的问题给全部解决啦。 f(4) <== 解决,告诉你。 main() 於是回到 main(),而你在得到解答後便 AC 啦。 在这里,f() 的规模越来越小,但都是相同的。 可能你一开始有 10 题不会,但到後面可能只剩 3 题、1 题、…,直到被全解。 也许 f(4) 只去问了 f(3) 共 7 题,但不先问到,也没办法完全解开; f(3) 只需要会那 7 题,但可能有个 4 题不会,也得先问到才算完全解开。 也许 f(0) 只需要会 1 题就好,但那是极关键。知道它後,连带的可以知道许多; 递回的运行,差不多就是这样子的。 另外丢个小问题给大家玩玩看好了。 如果告诉你 n 并给你 n 个数,怎麽求最小值为何呢? 以下附解答,慎入。 已知这 n 个数的最小值,要嘛在第 n 个数,要嘛在前 n-1 个数中。 於是我们可以将前 n-1 个数求最小值,看作一个新的 n 数求最小值问题。 已知若 n 为 1,则最小值即为该数;由此可知递回式如下: (设此 n 数为 a[1] ~ a[n]) f(1) = a[1]; f(n) = min(a[n], f(n-1)); 贴心文末防雷空页。 --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.240.202
1F:→ iForests:怎麽大家递回的例子都举这麽北七的 XD 10/09 22:08
2F:→ sa072686:举太高级并不会帮助理解啊XD 10/09 22:15
3F:推 ggm5566:56友情推 10/09 22:18
4F:推 csftwpt5566:5566 友情推 10/09 22:22







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP