1. 程式人生 > >演算法導論(第三版)-複習15動態規劃

演算法導論(第三版)-複習15動態規劃

15 動態規劃

1 課後習題

15.1-1 數學歸納法證明
15.1-2 總長6,(i=4,p=8),(i=3,p=5)
15.1-3 rn=max(pi-c+rni),i=1..n
15.1-4 紀錄每次切割i
15.1-5 頂點:0..n,邊:2*(n-2+1)

2 課後習題

15.2-1 m[i,k]+m[k+1,j]+pi1pkpj
((A1A2)((A3A4)(A5A6)))…詳見附件
15.2-2

F(A,s,i,j)
    if i==j
        return A[i];
    if i+1==j
        return mul(A[i]
,A[j]); M1=F(A,s,i,s[i,j]); M2=F(A,s,s[i,j]+1,j); return mul(M1,M2);

15.2-3 假設對任意k< n, P(k)>=c*2k
15.2-4 頂點:n2 邊:(n3n)/3 (無答案)
15.2-5
[i,j]=[i,i]+[i+1,j]=…=[i,j-1]+[j,j],所以連線(j-i)*2條
=>n(n-1)+(n-1)(n-2)+…+2+0=i2-i(i=2..n)=n(n+1)(2n+1)/6-1-n(i=2..n)=(n3n)/3
15.2-6 數學歸納法

3 課後習題

最優子結構和子問題重疊
15.3-1RECURSIVE-MATRIX-CHAIN:O(n3n1) time
enumerating:(4n/n3/2) time
詳見附件
15.3-2 略
15.3-3 具有
15.3-4 <1,1,2,3>
貪心:[1,3]=[1,1]+[2,3]+1*1*3=1*2*3+3=9
正確結果:[1,3]=[1,2]+[3,3]+1*2*3=1*1*2+6=8
15.3-5 最優子結構:問題的最優解由相關子問題的最優解組合而成,而這些子問題可以獨立求解。
因為此時每種長度的切割數被限制,也就是說此時使用長度i時,會影響子問題的l

i大小,是相關的。[但個人認為可以建立[rn,L],L為li集合,但是子問題的狀態數很大,幾乎等於窮舉了]
15.3-6 Dm=max{(Di-ci)ri,j}=max{Diri,j-ci*ri,j},兩個子問題相關,具有同樣變數ri,j

4 課後習題

LSC問題(最長公共子序列)O(mn)空間,O(m+n)時間重構
如果只計算長度:優化為一行多一點,但重構時間多
15.4-1 <1,0,1,0,1,0>,<1,0,0,1,1,0>,<1,0,1,0,1,1>,<0,1,0,1,0,1>
15.4-2 重構

if x[i]==y[i]
    ReLCS(c,x,y,i-1,j-1)
    print
else if c[i-1,j]>=c[i,j-1]
        ReLCS(c,x,y,i-1,j)
    else ReLCS(c,x,y,i,j-1)

15.4-3 略,根據公示即可
15.4-4 計算LSC長度

  1. 只是用表c中2*min(m,n)表項+O(1)額外空間:
  2. min(m,n)表項+O(1)額外空間:
    計算c[i,j]及之後結果需要用到c[i-1,k],k>=j-1或c[i,k],k<=j-1,所以空間一共一行+1,所以以min(m,n)為列數即可
    詳見附件

15.4-5 排序O(n lg n)與原字串求LSC,O(n2)
15.4-6

//Init:
cin>>a[]
c[0]=-1,c[1]=a[0]
for i=1 to n
    l=find(c,len,a[i]);//二分查詢,返回a[i]可加入位置(l)或不可(=len)
    c[l]=a[i];//因為此時可以保證a[i]<原c[l],所以下一個資料加入時,若>a[i],即c[l],但小於c[l+1],可更新c[l+1],且能保證之後的解至少等於或好於現在的解;若>c[len],相當於為原c陣列後再加資料,不影響解。唯一問題是,c中保留資料並不一定為解。
    if l>len
        len=l;//更新長度
5 課後習題

最優二叉搜尋樹
表e[1..n+1,0..n],因為只包含偽關鍵字dn, e[n+1,n],只包含偽關鍵字d0, e[1,0]
e[i,j]=qi1, (j==i-1) 或 min{e[i,r-1]+e[r+1,j]+w(i,j)}, (i<=j,令root[i,j]=r), (i<=r<=j)
w[i,j]=w[i,j-1]+pj+qj, w[i,i-1]=qi1
//個人理解,w為加入點的基本代價,而e為樹深增加的代價
時間O(n3)
15.5-1

if i<j
    root: r=root[i,j]
    lchild: root[i,r-1]
            F(root,i,r-1)
    rchild: root[r+1,j]
            F(root,r+1,j)
else if i==j
    root: r=i
    lchild: d[i-1]
    rchild: d[j]
else if i>j
    leaf: d[j]

15.5-2 略
15.5-3 重複計算,從qi1初始+(pi+qi)+…+(pj+qj),時間O(n)
但時間複雜度=O(n)O(n)(O(n)+O(n))=O(n3),不變
15.5-4 最優二叉搜尋樹,根root[i,j-1]<=root[i,j]<=root[i+1,j] 證演算法時間為 O(n2)

if i==j
    root:j
else for root=root[i,j-1] to root[i+1,j]

原:l=1 to n, i=1 to n-l+1, j=i+l-1, r=i to j ,時間O($n^3)
現:為了方便理解,我們書本側向root表看,加了約束以後,1<=root1,j-1<=root[1,j]<=root2,j<=root[2,j+1]<=root3,j+1<=…<=rootn-l+1,n-1<=root[n-l+1,n]<=root[n-l+2,n]<=n。
所以每一層,計算長度為l,只需計算n次,所以一共O(n2)

思考題

15-1 有向無環圖中的最長簡單路徑 Path(s,t)[無答案]
DAG->拓撲排序 時間複雜度O(n+e)
Init: L(i)=-infinite, L(s)=0
L(t)=max{L(i)+w(i,t)}, if e(i,t) exist 時間複雜度O(e)
重構路徑:if (L(u)-L(i)==w(i,u)) RePath(i)
所以整體O(n+e)

15-2 最長迴文子序列
解1:s’=reverse(s)
時間O(n2),如果不需要輸出具體內容的話可以減少到O(nlhn)(根據15.4-6)

  1. 將奇數/偶數長度的迴文子串都轉換成奇數長度:在每個字元的兩邊都插入一個特殊的符號。比如 abba 變成 #a#b#b#a#, aba變成 #a#b#a#。 為了進一步減少編碼的複雜度,可以在字串的開始加入另一個特殊字元,這樣就不用特殊處理越界問題,如$#a#b#a#
  2. 用陣列 P[i] 記錄以字元S[i]為中心的最長迴文子串向左/右擴張的長度(包括S[i],也就是把該回文串“對摺”以後的長度),P[i]-1正好是原字串中迴文串的總長度

    S # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 #
    P 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1

  3. 計算p[i]:id 為已知的 {右邊界最大} 的迴文子串的中心,mx則為id+P[id],也就是這個子串的右邊界。如果mx > i,那麼P[i] >= MIN(P[2 * id - i], mx - i)

    • 當 mx - i > P[j] 的時候,以S[j]為中心的迴文子串包含在以S[id]為中心的迴文子串中,由於 i 和 j 對稱,以S[i]為中心的迴文子串必然包含在以S[id]為中心的迴文子串中,所以必有 P[i] = P[j],見下圖。
      15-2-1
    • 當 P[j] >= mx - i 的時候,以S[j]為中心的迴文子串不一定完全包含於以S[id]為中心的迴文子串中,但是基於對稱性可知,下圖中兩個綠框所包圍的部分是相同的,也就是說以S[i]為中心的迴文子串,其向右至少會擴張到mx的位置,也就是說 P[i] >= mx - i。至於mx之後的部分是否對稱,就只能老老實實去匹配了。//其實此時,p[i]一定等於mx-i
      15-2-2
    • 對於 mx <= i 的情況,無法對 P[i]做更多的假設,只能P[i] = 1,然後再去匹配了。
  4. 程式碼如下:
//輸入,並處理得到字串s
int p[1000], mx = 0, id = 0;
memset(p, 0, sizeof(p));
for (i = 1; s[i] != '\0'; i++) {
    p[i] = mx > i ? min(p[2*id-i], mx-i) : 1;
    while (s[i + p[i]] == s[i - p[i]]) p[i]++;
    if (i + p[i] > mx) {
        mx = i + p[i];
        id = i;
    }
}
//找出p[i]中最大的

15-3 雙調歐幾里得旅行商問題 O(n2),任何兩點x座標均不相同,d[i,j]=min{i->1->j},i>=j,求d[n,n]

  1. 根據x座標排序,O(nlgn)
    • 當 j < i-1時,d[i,j]=d[i-1,j]+a[i-1,i]
    • 當 j = i-1時,d[i,j]=d[i,i-1]=min{a[i,k]+d[k,i-1]}, k=1..i-1
    • 當 j = i 時,d[i,j]=d[i,i]=min{d[i,k]+a[k,i]}, k=1…i-1
      詳見附件

15-4 整齊列印,行尾額外空格符ex[i,j]:Mj+ilk,(k=i..

相關推薦

演算法導論複習15動態規劃

15 動態規劃 1 課後習題 15.1-1 數學歸納法證明 15.1-2 總長6,(i=4,p=8),(i=3,p=5) 15.1-3 rn=max(pi-c+rn−i),i=1..n 15.1-4 紀錄每次切割i 15.1-5 頂點:0..n,

演算法導論複習 六部分圖論思考題 22 基本的圖演算法

22 基本的圖演算法 思考題 22-1 (以廣度優先搜尋來對圖的邊進行分類)深度優先搜尋將圖中的邊分類為樹邊、後向邊、前向邊和橫向邊。廣度優先搜尋也可以用來進行這種分類。具體來說,廣度優先搜尋將從源結點可以到達的邊劃分為同樣的4種類型。 a

演算法導論 課後習題解答

Perface:開始學習演算法導論,在這裡記錄自己的課後習題答案。希望自己能每天堅持更新一節的習題解答。 目前計劃的學習順序:第3部分資料結構和第5部分高階資料結構的全部內容 希望大家有什麼看不懂的地方可以提出來,我會盡量解答的; 如果有什麼出錯的地方,也希望大家能夠指正出來,萬分感謝! 於此同時,如

#006# 快速排序 × 演算法導論練習 7.1-1 ~ 7.1-4

快排採用經典的分治思想,具體如下↓ 分解:快排的核心步驟,其結果是陣列被分成以某個數為基準的左右兩個子陣列(可能為空),其中左邊的數都小於該基準數,右邊的數都大於該基準數。詳細步驟包括計算基準數下標,以及移動陣列內元素。 解決:通過遞迴呼叫快速排序,對兩個子陣列進行排序。 合併:因為是原址排序,快速排序

演算法導論練習 10.1-1 ~ 10.1-7 兩個棧實現佇列 兩個佇列實現棧

棧與佇列js實現版本: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title>

【讀書筆記】演算法導論第一章

練習: 1.1-1 給出現實生活中需要排序的一個例子或者現實生活中需要計算凸殼的一個例子 排序:淘寶銷量排序,凸殼:淘寶綜合排序 注:凸殼是一個點集中最小點集,就像一碗盛著飯的碗,凸殼就是那個碗 1.1-2 除速度外,在真實環境中還可能使用

演算法導論3》讀書筆記演算法基礎

本篇內容主要涉及《演算法導論》一書中的第二章知識,涉及的內容有插入排序和歸併排序 插入排序 對於插入排序有個很明顯的顯示生活例子來幫助我們理解,插入排序的工作原理就像打撲克牌一樣,右手從桌面上拿起一張牌,然後再左手那一堆已經按牌面大小排好序的牌找

深入理解計算機系統 練習2.15

練習題 2.15 只使用位級和邏輯運算,編寫一個C表示式,他等價於x==y。換句話說,當x和y相等時他將返回1,否則返回0 因為 x ^ y 只會在x == y時為0,所以我們可以利用這一性質得到這個

演算法導論英文版》電子書附下載連結+30個總結JVM虛擬機器的技術文排版好收藏版

技術書閱讀方法論 一.速讀一遍(最好在1~2天內完成) 人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結都會有特別好的作用。 對於每一章的知識,先閱讀標題,弄懂大概講的是什麼主題,再去快速看一遍,不懂也沒有關係,但是一定要在不懂的

《鳥哥的Linux私房菜-基礎學習篇

shell 怎樣學習 track col 網絡基礎 環境的使用 發生 企業網 clas 第2章 Linxu怎樣學習 1. Linux當前的應用角色 當前的Linux常見的應用可略分為企業應用和個人應用雙方面。 首先談了企業

《C算法.1卷,基礎、數據結構、排序和搜索》pdf

line tom 排序 歸並 簡介 systems sys 計算 ans 下載地址:網盤下載 內容簡介 · · · · · · 《C算法》介紹了當今最重要的算法,共分3卷,《C算法(第1卷):基礎、數據結構、排序和摸索》是第1卷。第1卷分4部

1014 C語言程序設計教程課後習題6.4

content += 教程 print ons ont c語言程序設計 lld cnblogs 題目描述 求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一個數字。 輸入 n 輸出 和 樣例輸入 5 樣例輸出 153 1 #include "stdio.h"

1013: C語言程序設計教程課後習題6.3

其中a是一個數字 blog += color turn sam c語言程序 [] c語言 題目描述 求Sn=a+aa+aaa+…+aa…aaa(有n個a)之值,其中a是一個數字。 例如:2+22+222+2222+22222(n=5),n由鍵盤輸入。 輸入 a 輸出 和 樣

1024: C語言程序設計教程課後習題7.3

c語言程序 print clas 程序 scanf col class pri printf 題目描述 求一個3×3矩陣對角線元素之和。 輸入 矩陣 輸出 主對角線 副對角線 元素和 樣例輸入 1 2 3 1 1 1 3 2 1 樣例輸出 3 7 1 #include

速讀《深入理解計算機系統》問題及解決

情況 csdn 第六章 填充 以及 函數 順序 時鐘 管理所 第一章 計算機漫遊 P13:用戶棧和運行時堆有什麽區別?數據結構中經常說堆棧,這裏的堆和棧一樣嗎?和操作系統的堆、棧有什麽區別? 參考:堆和棧的區別(內存和數據結構) 操作系統: 棧:由操作系統自動分配釋放

《構建之法》速讀提問

運用 其他 class share 漸進 順序 四種 適用於 生命周期 《構建之法(第三版)》速讀提問 1、什麽是軟件工程 軟件工程學科誕生後,人們為軟件工程給出了不同的定義,例如最早的定義是由F.L. Bauer給出的,即“軟件工程是為了經濟地獲得能夠在實際機器上高效運行

1046: C語言程序設計教程課後習題10.4

con n) 順序 調整 style char ++ 輸入數據 include 題目描述 有n個整數,使前面各數順序向後移m個位置,最後m個數變成前面m個數,見圖。寫一函數:實現以上功能,在主函數中輸入n個數和輸出調整後的n個數。 輸入 輸入數據的個數n n個整數 移動的位

《構建之法》第一章

include 四則運算 不但 目標 軟件需求 輸入 .com 不知道 設計與實現 1.軟件=程序(程序=算法+數據結構)+軟件工程 一個復雜的軟件不但要有合理的軟件架構、軟件設計與實現,還要有各種文件和數據來描述各個程序文件之間的依賴關系、編譯參數、鏈接參數等。這些都是

《構建之法》第二章

結束 快速 數據分析 來源 定義 很快 優化問題 回歸 自動 2.1單元測試 1.軟件的很多錯誤來源於程序員對模塊功能的誤解,疏忽或不了解模塊的變化。單元的測試可以讓自己負責的模塊功能定義盡量明確,模塊功能的改變不會影響其他模塊,而且模塊的質量能得到穩定的、量化的保證。 2

《下廚房》軟件系統需求分析報告

驗收測試 當下 登錄密碼 支持 服務器組件 系統設置 png internet 背景 《下廚房》軟件系統 需求分析報告 項目名稱 《下廚房》 所屬課程 軟件工程 項目