AlgoVerse

برش میله

میله‌ای به طول n را طوری ببُر که فروش تکه‌ها بیشترین درآمد را بدهد؛ جواب هر طول از جواب طول‌های کوتاه‌تر ساخته می‌شود.

میله‌ای به طول n داریم و prices[i − 1] قیمت تکه‌ای به طول i است. میله را چطور ببُریم (یا نبُریم) تا جمع قیمت تکه‌ها بیشترین شود؟ امتحان همه‌ی برش‌ها 2ⁿ⁻¹ حالت دارد.

ادامه‌ی توضیح ↓
ورودی:
n=8خروجی PDF

قیمت تکه‌های ۱ تا ۸؛ برای طول ۸ بهترین درآمد ۲۲ است (تکه‌های ۲ و ۶).

  1. def rod_cutting(prices):
  2. n = len(prices)
  3. r = [0] * (n + 1)
  4. cut = [0] * (n + 1)
  5. for j in range(1, n + 1):
  6. best = -1
  7. for i in range(1, j + 1):
  8. value = prices[i - 1] + r[j - i]
  9. if value > best:
  10. best = value
  11. cut[j] = i
  12. r[j] = best
  13. return r[n], cut

ناوردا: در شروع دور j، برای هر طول کوتاه‌تر از j، r بیشترین درآمد ممکن را دارد.

شروع اجرا

10518293104175176207

متغیرهای محلی

نارنجی = در همین گام عوض شد

prices list

158910171720

Call stack

  1. rod_cutting()خط 1
گام ۱ از ۱۷۸
خط سیاه = solved · خط نارنجی = گام کلیدیcompare: 0/36 · start: 0/8 · try_cut: 0/36 · new_best: 0/16 · solved: 0/8

    رشد تعداد عملیات با اندازه‌ی ورودی

    میانگین ۱۲ گراف تصادفی برای هر n (با seed ثابت). نشانگر توخالی = ورودی فعلی.

    • try_cut
    • ورودی فعلی (n=8)
    0204060804681012n = تعداد عضوهای آرایهtry_cut
    نمایش به شکل جدول
    ntry_cut
    410
    621
    836
    1055
    1278
    توضیح

    مسئله

    میله‌ای به طول n داریم و prices[i − 1] قیمت تکه‌ای به طول i است. میله را چطور ببُریم (یا نبُریم) تا جمع قیمت تکه‌ها بیشترین شود؟ امتحان همه‌ی برش‌ها 2ⁿ⁻¹ حالت دارد.

    ایده‌ی برنامه‌ریزی پویا

    در هر برش بهینه، اولین تکه طولی مثل i دارد و بقیه‌ی میله (طول j − i) هم باید بهینه بریده شده باشد. پس:

    r[j] = max over i of (prices[i − 1] + r[j − i])

    اگر r را از طول ۱ به بالا پر کنیم، هر بار جواب طول‌های کوتاه‌تر را آماده داریم. cut[j] طول اولین تکه را نگه می‌دارد تا خود برش‌ها را هم بشود بازسازی کرد.

    هزینه

    دو حلقه‌ی تودرتو: O(n²) به‌جای 2ⁿ.

    در trace به چه چیزی نگاه کنی

    • میله‌ها همان جدول r هستند که از چپ به راست پر می‌شود؛ فلش j طولی است که حل می‌شود.
    • با سطح جزئیات «هر دور حلقه» فقط پر شدن خانه‌های r را ببین.