Maximum Sum Subsequence

Programming Praxis | A collection of etudes, updated weekly, for the education and enjoyment of the savvy programmerというサイトにMaximum Sum Subsequence | Programming Praxisという問題があったので解いてみました。
cont-max2はほぼサイトに載っていた模範解答の最後のやつ(O(n)の解答)と同じでした。たcont-maxは最大値に加えて、最大になる部分数列も出力します。
数列を前から順番に見ていって、その時点での最大値と、一つ前の数列を使った最大値+今の値と、今の値を比較して大きい方を最大値に入れる、というのを繰り返してます。

(use gauche.collection)
(define (cont-max lst)
  (define (initseq val)
    (cons (list val) val))
  (let loop ((lst (cdr lst)) 
	     (prev-lst-max (initseq (car lst)))
	     (max (initseq (car lst))))
    (if (null? lst)
	max
	(let* ((new-lst-max (if (positive? (cdr prev-lst-max))
				(cons (cons (car lst) (car prev-lst-max)) (+ (car lst) (cdr prev-lst-max)))
				(initseq (car lst)))))
	  (loop (cdr lst)
		new-lst-max
		(find-max (list new-lst-max max) :key cdr))))))

(define (cont-max2 lst)
  (let loop ((lst (cdr lst)) (prev-lst-max (car lst)) (cur-max (car lst)))
    (if (null? lst)
	cur-max
	(let ((new-lst-max (if (positive? prev-lst-max) (+ prev-lst-max (car lst)) (car lst))))
	  (loop (cdr lst) new-lst-max (max cur-max new-lst-max))))))

gosh> (cont-max '(31  -41  59  26  -53  58  97  -93  -23  84))
((97 58 -53 26 59) . 187)

gosh> (cont-max2 '(31  -41  59  26  -53  58  97  -93  -23  84))
187

そういえば模範解答は最大値の初期値を0にしてしまっているので、最初の値が負の場合は、上手くいかない場合があります。

gosh> (max-sum-subsequence '(-31 -32 -123 -32))
0

どう見ても0ではない...


(10/12/07追記)
コメントにて、部分列は空列を含むので、空列の和を0とすると模範解答は正しいのではないかという指摘を受けました。言われてみると、確かにそう考えるほうが自然ですね。そうすると上の回答は間違ってて、loopのprev-lst-maxとcur-maxの初期値を0にしてlstの初期値をlstにしなければなりません。