Дараалсан тоонуудын хамгийн их нийлбэрийг ганц гүйлтээр олдог DP.
Эхлээд жижиг бодлого
a = [-2, 1, -3, 4, -1, 2, 1, -5, 4]. Дараалсан тоонуудын хамгийн их нийлбэр хэд вэ?
4 + (-1) + 2 + 1 = 6. Үүнээс их нийлбэртэй дараалсан хэсэг байхгүй. Хариу: 6.
Энгийн аргаас санаа руу
Энгийн арга: эхлэл l, төгсгөл r бүрийг сонгоод нийлбэрийг бодно. Prefix sum ашигласан ч O(n²), n = 100 000 бол 5 тэрбум алхам.
Гол санаа: i дээр дуусах хамгийн сайн хэсэг бол i − 1 дээр дуусах хамгийн сайн хэсэг дээр a[i]-г нэмсэн, эсвэл a[i] ганцаараа. Өмнөх нийлбэр сөрөг бол түүнийг авах нь зөвхөн хохиролтой. Тиймээс cur < 0 бол cur = 0 болгоод a[i]-г нэмнэ. Бүх cur-ийн хамгийн их нь хариу.
Нэр томьёо ба тэмдэглэгээ
- cur
- i дээр дуусах хамгийн их нийлбэртэй хэсгийн нийлбэр.
- best
- Одоог хүртэл олдсон хамгийн их нийлбэр.
LLONG_MINутгаас эхэлнэ. - subarray
- Array-н дундаас тасралтгүй авсан хэсэг:
a[l], a[l + 1], …, a[r]. - DP
- Том бодлогын хариуг жижиг бодлогынхоос гаргах. Энд шинэ cur нь өмнөх ганц cur-аас гарна.
Дараалсан тоонуудын нийлбэр хамгийн ихдээ хэд байх вэ? Сөрөг тоо байгаа тул бүгдийг нэмэх нь заавал зөв биш. Зүүнээс баруун тийш ганц удаа гүйгээд олъё.
- Space тоглуулах
- ←→ алхам
- −+ хурд
- a[i]
- Одоогийн хэсэг
- Шинэ cur
- Хамгийн их нийлбэртэй хэсэг
Хамгийн их нийлбэр
Дараалсан хэдэн тоо сонгоод нийлбэрийг нь хамгийн их болгоно. Хэсэг бүрийг шалгавал n × n орчим алхам болно. Kadane ганц удаа гүйгээд олно.
Дараа нь юу болох вэ?
Оноо 0 / 00дараалсан зөв, хамгийн их 0
Animation нэг алхам дээр зогсоно. Дараа нь код юу хийх вэ? Таагаад оноо цуглуул! Нэвтрэх хэрэггүй, оноо чинь энэ төхөөрөмж дээр хадгалагдана.
Юунд хэрэгтэй вэ?
Сөрөг тоотой array-д хамгийн их нийлбэртэй дараалсан хэсгийг n алхамд олно. Ашиг, оноо, температурын өөрчлөлт гэх мэт олон бодлогод гардаг.
Яаж ажилладаг вэ?
1. cur бол i дээр дуусах хэсгийн нийлбэр, best бол одоог хүртэлх хамгийн их нийлбэр. 2. cur сөрөг бол өмнөх хэсэг нийлбэрийг зөвхөн багасгана. Тиймээс cur = 0 болгож шинээр эхэлнэ. 3. cur += a[i]. 4. cur > best бол best = cur. Бүх тоо сөрөг байсан ч зөв ажиллана: тэдгээрийн хамгийн их нь (тэгт хамгийн ойр сөрөг тоо) хариу болно. Оролт: n, дараа нь n тоо.
Яагаад зөв, хэр хурдан бэ?
i дээр дуусах хэсэг бүр a[i]-гаас гадна i − 1 дээр дуусах хэсгийг агуулдаг, эсвэл огт агуулдаггүй. Хамгийн их нь max(cur + a[i], a[i]). Код яг үүнийг хийдэг: cur сөрөг бол хаяна. Бүх i-г шалгадаг тул хариу best-д заавал орно.
Ганц loop: хугацаа O(n), санах ой O(1). n = 10⁶ бол сая алхам.
Түгээмэл алдаа
- best-ийг 0-ээс эхлүүлэх. Бүх тоо сөрөг бол хариу 0 гарч буруу болно.
LLONG_MINэсвэл a[0]-ээс эхлүүл. - Нийлбэр int-ээс хэтрэх. a[i] ≤ 10⁹, n = 10⁵ бол 10¹⁴ хүрнэ.
long longашигла. - Хоосон хэсгийг зөвшөөрдөг эсэхийг анхаарах. Зөвшөөрдөг бол хариу хамгийн багадаа 0, үгүй бол сөрөг байж болно.
Хязгаарын тохиолдол
- Бүх тоо сөрөг, жишээ нь
[-3, -1, -2]: хариу −1, ганц тооноос тогтсон хэсэг. - Бүх тоо эерэг: хариу бүх array-н нийлбэр.
- n = 1: хариу a[0].
- Тэг ихтэй array:
[0, 0, 0]бол хариу 0.
Өөрийгөө шалга
a = [2, -1, 2]бол хариу хэд вэ?Хариу харах
3. Бүх array: 2 − 1 + 2.
a = [-5, -2, -8]бол хариу хэд вэ?Хариу харах
−2.
cur сөрөг болох нь юуг илэрхийлэх вэ?
Хариу харах
Өмнөх хэсгийг үргэлжлүүлэх нь ашиггүй. Шинэ хэсэг эхлүүлэх нь илүү.
Гурван дадлага
Hint-ээ нээхээс өмнө өөрөө оролдоорой.
1.
a = [3, -4, 5, -1, 2, -6, 4]дээр i бүрт cur, best-ийг бич.Hint харах
cur сөрөг болох бүрт дараагийн алхамд 0 болно.
Хариу ба тайлбар
cur: 3, −1, 5, 4, 6, 0, 4. best: 3, 3, 5, 5, 6, 6, 6. Хариу 6:
5 + (-1) + 2.2.Хариутай хамт хэсгийн эхлэл, төгсгөлийн index-ийг хэвлэ.
Hint харах
cur-ийг 0 болгох бүрт шинэ хэсэг i-гаас эхэлнэ.
Хариу ба тайлбар
startхувьсагч нэмнэ.cur = 0хийх үедstart = i. best шинэчлэгдэх үедL = start,R = iгэж хадгална.3.n × m хүснэгтийн хамгийн их нийлбэртэй тэгш өнцөгтийг ол. n, m ≤ 300.
Hint харах
Дээд, доод мөрийг сонгоод баганын нийлбэрүүд дээр Kadane ажиллуул.
Хариу ба тайлбар
Мөрийн хос бүрт баганын нийлбэрийг prefix sum ашиглан O(m) хугацаанд гаргаад Kadane хийнэ. Нийт O(n² · m) ≈ 27 сая алхам.
Жишээ
Оролт
9 -2 1 -3 4 -1 2 1 -5 4
Гаралт
6
Одоо өөрөө бодоод үз
Хичээл
Энэ сэдвийн хичээл удахгүй нэмэгдэнэ.