動態規劃的推廣
我對動態規畫( Dynamic Programming )的認識起於奧林匹亞研習營,有一次的專題便是動態規畫,其主要的內容是說在解決某些問題時,要求的答案其值決定於前面的值,而「前面」的值又決定於更前面的值。於是須要從前面一步一步的求值。
\r 舉一個簡單的例:費氏數列在數學上定義成
\r f(0)=1
\r f(1)=1
\r f(x)=f(x-1)+f(x-2)
\r 如果需要寫一個程式來計算的話,直覺的方法便是依照原本的定義,用遞迴來解決:
\r int=f(intx)
\r {
\r if(x \r returen f(x-1)+f(x-2);
\r }
\r \r 若要計算 f ( 5 )的話,其過程可由右圖來表示。 f ( 5 )的值取決於 ft4 )及 f ( a ) , f ( 4 ) 的值取決於 f ( 3 )及 f ( 2 ) ,這裡我們可以發現到, f ( a )在 f ( s )及 f ( 4 )中分別計算了一次,這便是浪費。再看得更詳細一點, f ( l )計算了 5 次, f ( 0 )計算了 3 次,如此算下來,其增長的速度是很可怕的。
\r 事實上,既然 f ( x )的值取決於 f ( x 一 1 ) , f ( x 一 2 )而 f ( x 一 l )的值又取決於 f ( x 一 2 ) , f ( x 一 3 ) , 那麼,我們便可由 fto )、 f ( 1 )、 f ( 2 )、 f ( 3 )二算到 f ( x ) ,這樣的話,所花的時問就變成線性的了。
\r 這時候,程式中可放置一陣列,以儲存所得到的經驗,例如:
\r int f(x)
\r {
\r int dp[max-x];
\r int, I;
\r dp[ 0]=1;
\r dp[ 1]=1;
\r for(i=2; i \r {
\r dp[ i]=dp[ i-1]+dp[i-2];//不必再遞迴了
\r }
\r retum dp[x];
\r }
\r 此外,動態規畫還有很多極為有趣的應用,因而,我展開了我的研究。
鄰升數在不取代與取代下的均值探討
本文章之最大鄰升數「升頂值q」與「附值點鄰集Ωnp,q」源於都市計畫遊戲「Tower Bloxx」,再由「相鄰數p=4」將q提升至5=p+1。 第一部分,研究「鄰升數總和S(p,q,Ω)」過程中,找出基數覆蓋法、鑲嵌法、通道法、邊角分析法與左右加格法。以矩形鑲嵌拼圖Bm×54,5、Bm×54,5合併上述方式處理Ωm×n4,5,得到 一般式S(4,5,m×n)。 第二部分,定義方格狀點鄰集Vm×np,推廣在p=3,…,8、q=2,…,p,p+1時的S(p,q,m×n)一般式。並利用均值找出「完美填數定理」與「不取代鄰升數總和上界S^(p,q,m×n) 」公式。 第三部分,以Ωm×np,q(0)=Ωm×np,q處理策略繼續尋找「可取代鄰升數總和R(p,q,Ω)」時,同樣發現中心鑲嵌法,再轉化成「匯流魚鱗{Fm'×n'p,q}」與「鋪瓦法〈Fi(tj)〉」找出Ωm×np,q(h)與 一般式R(p,q,m×n)。 第四部分,論述應用方向,並將平面中的Jn(p+1)p,q 應用在輪胎面與球面,改裝部分魔術方塊與定義新玩法。在解決球面填數時,額外發現切割五邊形幾項幾何性質。