有些問題在分解時會產生許多子問題,且分解出的自問題互相交織,因而在解這類問題時,將可能重複多次解乙個子問題。這種重複當然是不必要的,解決方法可以在解決每個子問題後把它的解(包括其子子問題的解)保留在乙個**中,若遇到求與之相同的子問題時,
dp演算法又稱動態規劃,是資訊學競賽中選手必須熟練掌握的一種演算法,
他以其多元性廣受出題者的喜愛.動態規劃首次進入資訊學奧賽是在ioi94
(數字三角形),在國內首次出現是在noi95。此後動態規劃成為資訊學奧
賽的必考演算法之一。
動態規劃一般可分為線性動規,區域動規,樹形動規,揹包動規四類。
舉例 線性動規:攔截飛彈,合唱隊形,挖地雷,建學校,劍客決鬥等
區域動規:石子合併, 加分二叉樹,統計單詞個數,炮兵布陣等
樹形動規:貪吃的九頭龍,二分查詢樹,聚會的歡樂,數字三角形等
揹包問題:01揹包問題,完全揹包問題,分組揹包問題,二維揹包,裝箱問題,
擠牛奶(同濟acm第1132題)等
應用例項
最短路徑問題 ,專案管理,網路流優化等
問題求解模式
動態規劃所處理的問題是乙個多階段決策問題,一般由初始狀態開始,通過對中間階段決策
的選擇,達到結束狀態。這些決策形成了乙個決策序列,同時確定了完成整個過程的一條活
動路線(通常是求最優的活動路線)。如圖所示。動態規劃的設計都有著一定的模式,一般要
經歷以下幾個步驟: 初始狀態→│決策1│→│決策2│→…→│決策n│→結束狀態
(1)劃分階段:按照問題的時間或空間特徵,把問題分為若干個階段。在劃分階段時,注意劃
分後的階段一定要是有序的或者是可排序的,否則問題就無法求解
(2)確定狀態和狀態變數:將問題發展到各個階段時所處於的各種客觀情況用不同的狀態表示
出來。當然,狀態的選擇要滿足無後效性。
(3)確定決策並寫出狀態轉移方程:因為決策和狀態轉移有著天然的聯絡,狀態轉移就是根據
上一階段的狀態和決策來匯出本階段的狀態。所以如果確定了決策,狀態轉移方程也就可寫出。但
事實上常常是反過來做,根據相鄰兩段各狀態之間的關係來確定決策。
(4)尋找邊界條件:給出的狀態轉移方程是乙個遞推式,需要乙個遞推的終止條件或邊界條件。
演算法實現
動態規劃的主要難點在於理論上的設計,也就是上面4個步驟的確定,一旦設計完成,實現部分就
會非常簡單。使用動態規劃求解問題,最重要的就是確定動態規劃三要素:問題的階段,每個階段
的狀態以及從前乙個階段轉化到後乙個階段之間的遞推關係。遞推關係必須是從次小的問題開始到
較大的問題之間的轉化,從這個角度來說,動態規劃往往可以用遞迴程式來實現,不過因為遞推可
以充分利用前面儲存的子問題的解來減少重複計算,所以對於大規模問題來說,有遞迴不可比擬的
優勢,這也是動態規劃演算法的核心之處。
動態規劃演算法將問題的解決方案視為一系列決策的結果,與貪婪演算法不同的是,在貪婪演算法中,
每採用一次貪婪準則,便做出乙個不可撤回的決策;而在動態規劃演算法中,還要考察每個最優決策
序列中是否包含乙個最優決策子串行,即問題是否具有最優子結構性質。 動態規劃演算法的有效性依
賴於待求解問題本身具有的兩個重要性質:最優子結構性質和子問題重疊性質。
(1)最優子結構性質。如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題
具有最優子結構性質(即滿足最優化原理)。最優子結構性質為動態規劃演算法解決問題提供了重要線索。
(2)子問題重疊性質。子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產
生的子問題並不總是新問題,有些子問題會被重複計算多次。
動態規劃演算法正是利用了這種子問題的重疊性質,對每乙個子問題只計算一次,然後將其計算
結果儲存在乙個**中,當再次需要計算已經計算過的子問題時,只是在**中簡單地檢視一下結果,
從而獲得較高的解題效率。 當我們已經確定待解決的問題需要用動態規劃演算法求解時,通常可以按照以
下步驟設計動態規劃演算法:
(1)分析問題的最優解,找出最優解的性質,並刻畫其結構特徵;
(2)遞迴地定義最優值;
(3)採用自底向上的方式計算問題的最優值;
(4)根據計算最優值時得到的資訊,構造最優解。
1~3步是動態規劃演算法解決問題的基本步驟,在只需要計算最優值的問題中,完成這三個基本步驟就
可以了。如果問題需要構造最優解,還要執行第4步;此時,在第3步通常需要記錄更多的資訊,以
便在步驟4中,有足夠的資訊快速地構造出最優解。
例如:1
b -最少攔截系統
time limit:1000ms memory limit:32768kb 64bit io format:%i64d & %i64u
submitstatus
description
某國為了防禦敵國的飛彈襲擊,發展出一種飛彈攔截系統.但是這種飛彈攔截系統有乙個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能超過前一發的高度.某天,雷達捕捉到敵國的飛彈來襲.由於該系統還在試用階段,所以只有一套系統,因此有可能不能攔截所有的飛彈.
怎麼辦呢?多搞幾套系統唄!你說說倒蠻容易,成本呢?成本是個大問題啊.所以俺就到這裡來求救了,請幫助計算一下最少需要多少套攔截系統.
input
輸入若干組資料.每組資料報括:飛彈總個數(正整數),飛彈依此飛來的高度(雷達給出的高度資料是不大於30000的正整數,用空格分隔)
output
對應每組資料輸出攔截所有飛彈最少要配備多少套這種飛彈攔截系統.
sample input
8 389 207 155 300 299 170 158 65
sample output
dp演算法的思路就是由前面最優的情況來推算最優情況。對於這種題目還存在很多模板,
希望大家在以後的做題中,慢慢探索,慢慢總結。
動態規劃法
在學習動態規劃法之前,我們先來了解動態規劃的幾個概念 1 階段 把問題分成幾個相互聯絡的有順序的幾個環節,這些環節即稱為階段。2 狀態 某一階段的出發位置稱為狀態。3 決策 從某階段的乙個狀態演變到下乙個階段某狀態的選擇。4 狀態轉移方程 前一階段的終點就是後一階段的起點,前一階段的決策選擇匯出了後...
動態規劃法
最近遇到了一道挺有意思的演算法題 四種硬幣 1元3元4元5元 問 想要湊成n元錢最少幾枚硬幣?public class coinsgamemain fun 7,is public static void fun int k,int is i1 l min i2 if l k private stat...
動態規劃法
動態規劃的關鍵點 動態規劃演算法的兩種形式 舉乙個簡單的例子 就斐波拉契數列fibonacci fibonacci n 1 n 0 fibonacci n 1 n 1 fibonacci n fibonacci n 1 fibonacci n 2 一 首先使用遞迴版本實現這個演算法 public i...