動態規劃中遞推式的求解方法不是動態規劃的本質。
- 動態規劃的本質,是對問題狀態的定義和狀態轉移方程的定義。
引自維基百科
dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems.
動態規劃是通過拆分問題,定義問題狀態和狀態之間的關係,使得問題能夠以遞推(或者說分治)的方式去解決。
本題下的其他答案,大多都是在說遞推的求解方法,但如何拆分問題,纔是動態規劃的核心。
而拆分問題,靠的就是狀態的定義和狀態轉移方程的定義。
1. 什麼是狀態的定義?
**
首先想說大家千萬不要被下面的數學式嚇到,這裏只涉及到了函數相關的知識。**
我們先來看一個動態規劃的教學必備題:
給定一個數列,長度爲N,
求這個數列的最長上升(遞增)子數列(LIS)的長度.
以
1 7 2 8 3 4
爲例。
這個數列的最長遞增子數列是 1 2 3 4,長度爲4;
次長的長度爲3, 包括 1 7 8; 1 2 3 等.
要解決這個問題,我們首先要定義這個問題和這個問題的子問題。
有人可能會問了,題目都已經在這了,我們還需定義這個問題嗎?需要,原因就是這個問題在字面上看,找不出子問題,而沒有子問題,這個題目就沒辦法解決。
所以我們來重新定義這個問題:
給定一個數列,長度爲N,
設爲:以數列中第k項結尾的最長遞增子序列的長度.
求 中的最大值.
顯然,這個新問題與原問題等價。
而對於來講,都是的子問題:因爲以第k項結尾的最長遞增子序列(下稱LIS),包含着以第中某項結尾的LIS。
上述的新問題也可以叫做狀態,定義中的“爲數列中第k項結尾的LIS的長度”,就叫做對狀態的定義。
之所以把做“狀態”而不是“問題” ,一是因爲避免跟原問題中“問題”混淆,二是因爲這個新問題是數學化定義的。
對狀態的定義只有一種嗎?當然不是。
我們甚至可以二維的,以完全不同的視角定義這個問題:
給定一個數列,長度爲N,
設爲:
在前i項中的,長度爲k的最長遞增子序列中,最後一位的最小值. .
若在前i項中,不存在長度爲k的最長遞增子序列,則爲正無窮.
求最大的x,使得不爲正無窮。
這個新定義與原問題的等價性也不難證明,請讀者體會一下。
上述的就是狀態,定義中的“爲:在前i項中,長度爲k的最長遞增子序列中,最後一位的最小值”就是對狀態的定義。
- 什麼是狀態轉移方程?
上述狀態定義好之後,狀態和狀態之間的關係式,就叫做狀態轉移方程。
比如,對於LIS問題,我們的第一種定義:
設爲:以數列中第k項結尾的最長遞增子序列的長度.設A爲題中數列,狀態轉移方程爲:
(根據狀態定義導出邊界情況)
A_{i}, i\in (1..k-1)) ” eeimg=”1”>1)” eeimg=”1”>
用文字解釋一下是:
以第k項結尾的LIS的長度是:保證第i項比第k項小的情況下,以第i項結尾的LIS長度加一的最大值,取遍i的所有值(i小於k)。
第二種定義:
設爲:在數列前i項中,長度爲k的遞增子序列中,最後一位的最小值設A爲題中數列,狀態轉移方程爲:
若F_{i-1,k-1}” eeimg=”1”>則
否則:
(邊界情況需要分類討論較多,在此不列出,需要根據狀態定義導出邊界情況。)
大家套着定義讀一下公式就可以了,應該不難理解,就是有點繞。
這裏可以看出,這裏的狀態轉移方程,就是定義了問題和子問題之間的關係。
可以看出,狀態轉移方程就是帶有條件的遞推式。
3. 動態規劃迷思
本題下其他用戶的回答跟動態規劃都有或多或少的聯繫,我也講一下與本答案的聯繫。
a. “緩存”,“重疊子問題”,“記憶化”:
這三個名詞,都是在闡述遞推式求解的技巧。以Fibonacci數列爲例,計算第100項的時候,需要計算第99項和98項;在計算第101項的時候,需要第100項和第99項,這時候你還需要重新計算第99項嗎?不需要,你只需要在第一次計算的時候把它記下來就可以了。
上述的需要再次計算的“第99項”,就叫“重疊子問題”。如果沒有計算過,就按照遞推式計算,如果計算過,直接使用,就像“緩存”一樣,這種方法,叫做“記憶化”,這是遞推式求解的技巧。這種技巧,通俗的說叫“花費空間來節省時間”。都不是動態規劃的本質,*不是動態規劃的核心。*
b. “遞歸”:
遞歸是遞推式求解的方法,連技巧都算不上。
c. “無後效性”,“最優子結構”:
上述的狀態轉移方程中,等式右邊不會用到下標大於左邊i或者k的值,這是”無後效性”的通俗上的數學定義,符合這種定義的狀態定義,我們可以說它具有“最優子結構”的性質,在動態規劃中我們要做的,就是找到這種“最優子結構”。
在對狀態和狀態轉移方程的定義過程中,滿足“最優子結構”是一個隱含的條件(否則根本定義不出來)。對狀態和“最優子結構”的關係的進一步解釋,什麼是動態規劃?動態規劃的意義是什麼? - 王勐的回答 寫的很好,大家可以去讀一下。
需要注意的是,一個問題可能有多種不同的狀態定義和狀態轉移方程定義,存在一個有後效性的定義,不代表該問題不適用動態規劃。
動態規劃方法要尋找符合“最優子結構“的狀態和狀態轉移方程的定義,在找到之後,這個問題就可以以“記憶化地求解遞推式”的方法來解決。而尋找到的定義,纔是動態規劃的本質。