這裡說一下動規的基本思想,本思想僅僅截止於2020.6.26日,今後我如果對動規有新理解,將會持續更新。
首先動規講究兩個原則:
(我感覺目前我自己對這兩個原則理解還不是很深刻,因為做的題還不夠,就僅僅講講目前的理解,以作為記錄)
1、最優化原則
一本通上有一句話說的很好:
乙個問題的區域性最優將導致整個問題最優動態規劃我目前遇到的題基本上都是用來解決最優解問題,例如找出最少花費啊,最優路徑啊等等等等。而在解題的過程中,肯定是一步步求解,每一步就相當於乙個子問題,在做題時你就會發現,你的每個子問題也是按著最優解去求的,所以最終的結果一定是最優的。
此處必須要提一下貪心法,有的小夥伴(包括我)之前也一直認為貪心法的每一步也是最優解,因為每次都會去找乙個最好的嘛,但其實不然,貪心的區域性看似最優,但最後往往得不到整體最優,所以侷限性很大。具體與貪心的區別我以後大概會寫吧
2.無後效性原則
一本通上又一句話說得好:
某階段的狀態一旦確定,則此後的過程演變不再受此前各狀態及決策的影響我的理解是什麼呢,就是某乙個決策一旦確定,那麼你的這個決策一定是最優的,且對整體而言也是最優的,你以後的資料,決策絕對不會對之前的決策有任何的影響,但是你的之前的這個決策會對後面你即將做出的決策產生影響,這是一定的,畢竟一步步算嘛,前人鋪路,後人乘涼嘛。
簡單地說,決策一旦下達,便是一錘定音,不會再更改
如果你在寫動規的過程中,遇到了前後決策糾纏不清的情況,大概要重新梳理一下思路了。
以下題目來自奧賽一本通,評測**:1、數字金字塔【題目描述】
觀察下面的數字金字塔。寫乙個程式查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以從當前點走到左下方的點也可以到達右下方的點。
在上面的樣例中,從13到8到26到15到24的路徑產生了最大的和86。
【題目描述】
第乙個行包含r(1≤ r≤1000),表示行的數目。
後面每行為這個數字金字塔特定行包含的整數。
所有的被**的整數是非負的且不大於100。
【輸出】
單獨的一行,包含那個可能得到的最大的和。
【輸入樣例】
5【輸出樣例】 哈哈1311 8
12 7 26
6 14 15 8
12 7 13 24 11
這個題可有意思了,作為入門引例真的再合適不過了
首先第一想法是不是貪心法亞
對嘛,我每一次都選個大的加上去,結果不就大了嗎!
很遺憾,不對呀 阿sir~~
你康康,加入從第乙個開始,每一次向下都選擇數字最大的,那麼就是
13 --> 11 --> 12 --> 14 -->13 == 63 < 86不對呀,是吧。所以看來只能用動態規劃了。
這道題告訴我們做人不要貪心亞,只顧眼前利益而不看長遠,這定律感覺在各個領域都適用呢~~
那麼問題來了,動態規劃怎麼搞呢?
這裡我說一下正推法,至於倒退法請讀者(我自己)自己去想!!!!(想不明白看書!!)
首先 我們要設立乙個陣列b[i][j],存放乙個很關鍵的東西:
當前決策的最優解的值
然後我們一步一步看
當我們從最頂部開始:13 此時沒有別的點,就他乙個,那麼此時最優解就是他自己b[1][1]=13
然後看第二層:11 和 8 此時兩者都只連線了乙個 13 所以此時這兩個點的最優解 是他們自己的值加上之前確定好的最優值13
即b[2][1]=13+11=24
b[2][2]=13+8=21
然後第三層
12這個點,只有一條路到達他 所以b[3][1]=b[2][1]+12=45
7這個點,有兩條路可以到達他 由於之前的決策已經確定,一定為最優解,所以選擇乙個最大的即可:b[3][2]=b[2][1]+7=31
(有同學可能會問了,這裡你也是選最大的啊,為啥就不叫貪心法了呢?這裡最大的區別就是上面的決策是已經確定好了的最優解,所以我敢直接加上去,這就是最微妙之處,請你後來看的時候務必細細體會這裡,這裡就是利用了無後效性原則,我敢加就是因為我知道後面的決策不會對前面有影響,但貪心就不一樣了,後面的可能就會對前面造成影響,使其不是最優解)
26這個點,也只有一條路可以到達
b[3][3]=b[2][2]+26=47
按著這個思想,一步一步向下類推,最後的最大值就是答案咯
下面上**啦!(你一定能看明白的w!!! )
#include
#include
#include
#include
#include
using
namespace std;
intmain()
}for
(int i=
2;i<=n;i++
)else}}
int temp;
for(
int i=
1;i<=n;i++)}
cout<
/*cout
int t=1;
for(int i=2;i<=n-1;i++)
cout
這裡小小總結一下:
如果你覺得這個題能用動規做,那麼一定就能找到乙個最原始的乙個部分,他的最優值是已經確定下來的,作為第一步決策,就像上面題中的第乙個點13,然後再順著一步一步的走下去。
另外,所給資料一定是有順序的,或者是可以排序的,這樣你才能寫迴圈一步一步去求解。
(還有乙個最長不下降子串行的題目,今天太晚了,明天寫!!!!! )
ACM 階段性總結 ACM 動態規劃 DP
這短時間看了 揹包九講 看到揹包問題解法中的優美之處也看到揹包問題在現實中的應用,總結出一句話 揹包問題值得一看。揹包問題可以概括為這樣的模型 有若干種選擇,每種選擇有一定的代價和價值,做某些選擇會得到特定的狀態,問我們在約定的條件下怎麼得到特定的狀態?這裡的狀態可以是代價和或者價值和或者由其他這兩...
階段性總結
今天聽學長交流了一些人生的經驗,便有了一些感觸,加上對自己最近的學習狀態的總結,就寫一篇部落格給自己一點指示。最近渾渾噩噩的,有幾次考試也沒考好,考後也沒總結。晚自習本想刷一些題,複習一下,或是學習一點技術。看見其他同學在打擺,便動搖了。最後心中也只是徒留深深的罪惡感。所以我也是時候對自己的未來進行...
階段性總結
感覺上個星期還挺痛苦的,因為要練演算法,每個人都告訴我說演算法很重要很重要,但是演算法對我來說就像是一根很亂的神經,一觸就炸了,可我的驕傲還不允許我放棄。在leetcode上練習的時候是直接告訴用什麼方法,在寫藍橋杯演算法的時候就像是閱讀理解,經常讀不懂是什麼意思,要不就是理解錯誤,追根究底還是做的...