Динамическое программирование - нарезка стержней

На днях я смотрел CLRS, чтобы немного освежить свою память, и наткнулся на классический проблема резки стержня.

Классическое восходящее решение для этого следующее:

1: let r[0..n] be a new array
2: r[0] = 0
3: for j = 1 to n
4:    q = -1
5:    for i = 1 to j
6:       q = max(q, p[i] + r[j-i])
7:    r[j] = q
8: return r[n]

Теперь есть кое-что, о чем я все время думаю. Почему мы продолжаем повторно использовать p [i] на L.6? Я имею в виду, что, допустим, у нас есть j = 4, тогда он будет вычислять следующие комбинации:

1 + 3
2 + 2
3 + 1
4 + 0

какой смысл вычислять «3 + 1» дважды. Я предлагаю не использовать p [], а использовать только r [] и остановиться на этаже (j / 2).

1: let r[0..n] be a new array
2: r[0] = 0
3: for j = 1 to n
4:    q = p[j]
5:    for i = 1 to floor(j/2)
6:       q = max(q, r[i] + r[j-i])
7:    r[j] = q
8: return r[n]

Кто-нибудь видит что-то не так в этом подходе?

Спасибо,

6
задан Jean-Pascal Billaud 25 August 2011 в 23:56
поделиться