Для задачи «резка стержня»:
Учитывая стержень длиной n дюймов и массив цен, который содержит цены на все кусочки размером меньше n. Определите максимальное значение, которое можно получить, разрезая прут и продавая кусочки. [ ссылка ]
Введение в алгоритмы (CLRS) на стр. 366 приведен этот псевдокод для восходящего (динамического программирования) подхода:
1. BOTTOM-UP-CUT-ROD(p, n)
2. let r[0 to n]be a new array .
3. r[0] = 0
4. for j = 1 to n
5. q = -infinity
6. for i = 1 to j
7. q = max(q, p[i] + r[j - i])
8. r[j] = q
9. return r[n]
Теперь у меня проблемы с пониманием логики, стоящей за строкой 6. Почему они делают max(q, p[i] + r[j - i])
вместо max(q, r[i] + r[j - i])
? Поскольку это подход снизу вверх, сначала мы вычислим r[1]
, а затем r[2], r[3]...
. Это означает, что при вычислении r [x] у нас гарантированно будет r [x - 1].
r [x] обозначает максимальное значение, которое мы можем получить для стержня длины x (после обрезки до максимизации прибыли), тогда как p [x] обозначает цену одного куска стержня длины x. Строки 3-8 вычисляют значение r[j]
для j = 1 до n, а строки 5-6 вычисляют максимальную цену, за которую мы можем продать стержень длины j, рассматривая все возможные сокращения. Итак, как же имеет смысл использовать p [i] вместо r [i] в строке 6. Если мы пытаемся найти максимальную цену за стержень после того, как мы разрезаем его на длину = i, не следует ли нам добавить цены из r [i] и r [j - 1]?
Я использовал эту логику для написания кода Java, и, похоже, он дает правильный вывод для ряда тестовых случаев, которые я пробовал. Я пропускаю некоторые случаи, когда мой код приводит к неправильным / неэффективным решениям? Пожалуйста, помогите мне. Спасибо!
class Solution {
private static int cost(int[] prices, int n) {
if (n == 0) {
return 0;
}
int[] maxPrice = new int[n];
for (int i = 0; i < n; i++) {
maxPrice[i] = -1;
}
for (int i = 1; i <= n; i++) {
int q = Integer.MIN_VALUE;
if (i <= prices.length) {
q = prices[i - 1];
}
for (int j = i - 1; j >= (n / 2); j--) {
q = Math.max(q, maxPrice[j - 1] + maxPrice[i - j - 1]);
}
maxPrice[i - 1] = q;
}
return maxPrice[n - 1];
}
public static void main(String[] args) {
int[] prices = {1, 5, 8, 9, 10, 17, 17, 20};
System.out.println(cost(prices, 8));
}
}