我试图记住如何在懒惰的球拍中进行动态编程。在我解决了 Project Euler 的一个问题后,我开始怀疑这一点:
通过从下方三角形的顶部开始并移动到下方行中的相邻数字,从上到下的最大总数为 23。
3 7 4 2 4 6 8 5 9 3
也就是说,3 + 7 + 4 + 9 = 23。
求下面三角形从上到下的最大总数:...
我用下面的代码解决了这个问题。然而,我在学校里被教过惰性球拍(实际上是一般的编程语言),我似乎记得在惰性语言中,解决动态编程问题要容易得多。例如,在其他 eulerists 发布的解决方案中,一个人发布了他用来解决问题的 haskell 代码,而实际上只需要一行代码就可以指定问题中的数据(三角形中的内容是什么)本身)。但是,我不理解代码,所以我仍然感到困惑。
概括:
- 如何解决惰性球拍中的动态编程问题?例如,答案可能会解决上面给出的 4 级三角形示例(而不是完整的 15 级三角形)问题,或者发布一些以前制作的编辑距离代码(这就是我学习 DP 的方式)。
- 为什么用惰性语言(例如惰性球拍)做动态编程更容易?
下面给出了我用来解决常规球拍中 DP 问题的 80 行代码。
#lang racket
(define (triangle-ref x y)
(let ((triangle
(vector-immutable
(vector-immutable 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23)
(vector-immutable 63 66 04 68 89 53 67 30 73 16 69 87 40 31)
(vector-immutable 91 71 52 38 17 14 91 43 58 50 27 29 48)
(vector-immutable 70 11 33 28 77 73 17 78 39 68 17 57)
(vector-immutable 53 71 44 65 25 43 91 52 97 51 14)
(vector-immutable 41 48 72 33 47 32 37 16 94 29)
(vector-immutable 41 41 26 56 83 40 80 70 33)
(vector-immutable 99 65 04 28 06 16 70 92)
(vector-immutable 88 02 77 73 07 63 67)
(vector-immutable 19 01 23 75 03 34)
(vector-immutable 20 04 82 47 65)
(vector-immutable 18 35 87 10)
(vector-immutable 17 47 82)
(vector-immutable 95 64)
(vector-immutable 75))))
(vector-ref (vector-ref triangle y) x)))
(define triangle-size 15)
(define (problem18)
(let ((table (let fill-table ((table (hash))
(current-x 0)
(current-y 0))
(cond ((>= current-y triangle-size) table)
((>= current-x (- triangle-size current-y))
(fill-table table 0 (add1 current-y)))
(else (let ((reference (cons current-x current-y))
(triangle-value (triangle-ref current-x
current-y)))
(if (= current-y 0)
(fill-table (hash-set table
reference
(cons triangle-value
empty))
(add1 current-x)
current-y)
(let* ((left-entry (hash-ref
table
(cons
current-x
(sub1 current-y))))
(left-cost (car left-entry))
(left-path (cdr left-entry))
(right-entry (hash-ref
table
(cons
(add1
current-x)
(sub1
current-y))))
(right-cost (car right-entry))
(right-path (cdr right-entry)))
(if (> left-cost right-cost)
(fill-table (hash-set table
reference
(cons
(+ triangle-value
left-cost)
(cons
triangle-value
left-path)))
(add1 current-x)
current-y)
(fill-table (hash-set table
reference
(cons
(+ triangle-value
right-cost)
(cons
triangle-value
right-path)))
(add1 current-x)
current-y))))))))))
(car (hash-ref table (cons 0 (sub1 triangle-size))))))
(problem18)
(provide problem18)