or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
matrix chain
連鎖舉陣列相乘
定義:給定n個矩陣,求最小合併成本,對於兩個相鄰矩陣,都是可以乘的合法矩陣
存法
對於每個矩陣的行跟列,因為前一矩陣的行等於下一個矩陣的列,所以只要存一次就好了
重要:除了頭尾的元素,每個都可以代表前一個矩陣的列和當前矩陣的行
演算法
DP & Recursion
對於每個區段(l,r)都去找分割點k,分成左右,左右再各自遞迴,最後再把兩邊遞迴的結果合併,對於每次合併,都只會選擇(l+1~r-1)的元素來消除,所以l和r是會一直留著的,最後的合併就會是a[l]*a[k]矩陣和a[k]*a[r]矩陣 (a代表矩陣的行或列)
假設:1 2 5 7 3 9選擇5來分割
分別代表
兩邊都各自遞迴直到只剩一個矩陣
最後的狀態:
合併:
狀態轉移為:
印出優先順序
要印出優先順序,首先要知道切哪邊成本最小,所以對於每次求出區間(l,r)的分割點k,存在一個陣列(cut[l][r])裡,該陣列存放(l,r)區間最小成本的分割點k,所以對於每個區間最後要輸出的都是
因為根據狀態轉移,我們"分割"然後"合併",所以"分割"左右就讓遞迴去跑,最後會傳合併後的結果,找完分割點的"合併"就是' * ',終止條件是l==r,只剩一個矩陣就不用合併,大於兩個才要
要注意的是:
index=每個矩陣的編號=每個矩陣的行
遞迴求優先順序時,是以index來遞迴,因為要印出編號,所以以編號(每個矩陣的行)來遞迴會比較方便,要注意印出結果的遞迴是呼叫print(0,n-1),而求最小合併成本的遞迴是rec(0,n)
為了方便print的呼叫,cut要以index為參數,也就是該矩陣的行。因為(l,r)區間的r是右界元素的列,所以在紀錄cut的時候要記錄在cut[l][r-1]才會是右界元素的index(右界元素的行)
分割時,左邊的k代表左邊右界矩陣的列,右邊的k代表右邊左界矩陣的行,所以呼叫print左邊時,要變成cut[l][r]-1才會是左邊右界的index
c112: 00348 - Optimal Array Multiplication Sequence