DP(動態規劃)個人學習 初步

2021-07-26 11:45:50 字數 2071 閱讀 7818

動態規劃是一種重要演算法,其思想,在我個人理解來看,就是把問題逐步地進行簡化,從乙個看似複雜的問題,將問題化小,簡化到可以用某條公式(狀態轉移方程)逐步求出每種狀態的解,直到最後求出所要的答案。

比如01揹包問題,揹包容量有限,要盡可能裝入價值大的物品,我們可以假設乙個dp陣列,其中dp[j]表示在容量為j的情況下最多能裝入多少價值的物品,這樣就把問題簡化到求乙個個狀態了,但是明顯還是不夠用來解決問題,那麼怎麼辦呢?想想:對於每一種物品,都有裝入和不裝入兩種選擇,於是多了這麼一中約束條件:裝\不裝。又由於每種物品只有一件,所以應該從後往前更新,保證每種物品只被裝入一遍,這樣一步步推下來,就得到了我們所要的狀態轉移方程:

dp[j] = max

具體**則要寫成這樣:

for(int i = 0; i < n ;i++)

for(int j = w; j >= w[i]; j--)

dp[j] = max(dp[j], dp[j-w[i]]+v[i]);

好像有點難以理解?其實就是一種數學思想,做動態規劃要對狀態的轉移有足夠清晰的思路,最後還得回到

做題上。下面是hdu上乙個關於dp的題目組,要掌握好各種演算法最最最主要的還是多做題!

題目意思就是給一串數字,要你求出其中和最大的子串行,輸出最大的和,子串行的起始和結束點。

如何做這道題呢?首先簡化下問題,我們可以求到每個數字時以這個數字為結尾的最大子串行和是多少,於是dp陣列出來了,接下來,如何實現狀態轉移?考慮這樣一件事實:對於每乙個a[i],dp[i-1]都有加或不加的權利,如果加上他能使其接近答案,那麼就加上。怎樣才算接近答案呢?如果該dp[i-1]大於0,那麼無疑可以加上,不管加上後是正是負在以後的狀態轉移中再來篩除。如果dp[i-1]小於0,那麼這一段可以捨棄掉了,直接從當前數字起始,即dp[i] = a[i]。方程出來了!

上面說的有點繁瑣,主要為了初學者和自己便於理解,具體見**,不正確的地方還請大牛指正!

#include #include #include using namespace std;

int a[100000+20], dp[100000+20];

int main()

}left = right; // 這一句非常重要,漏了這句wa了十幾次,因為要考慮到子串行是乙個數的結果,這個初始化不能少

for(int i = left-1; i >= 0; i--)

printf("case %d:\n%d %d %d\n", j++, maxn, left+1, right+1);

if(t)

printf("\n");

return 0;

}}

接下來是1003的公升級版:hdu-1024  max sum plus plus

題目意思與上面差不多,改變的是這次要求多段子序列和最大。

這次加了個條件,求n段的子串行的最大和。如何入手呢?首先先寫一下二維的dp方程:

dp[i][j] = max + s[i]

dp[i][j]表示前j個數字的i個子序列最大和是多少,很好,狀態轉移方程不難寫出,接下來考慮一下如何優化?二維的寫法我也不是很會寫,能化成一維就更好了。思考一下:在我們的方程中,用到了什麼?其實也只有當前狀態(dp[i][j-1])和上乙個狀態(dp[i-1][k])而已!於是可以用兩個一維陣列表示。

#include #include #include typedef long long ll;

using namespace std;

int s[1000000+20];

ll cur[1000000+20], pre[1000000+20];

int main()

memset(cur, 0, sizeof(cur)); // 當前狀態

memset(pre, 0, sizeof(pre)); // 上一次狀態

for(int i = 1; i <= m; i++)

pre[j-1] = maxsum;

}printf("%lld\n", maxsum);

}return 0;

}

未完待更。。。

個人學習規劃

我目前是一位大二學生,我的專業是信管,這個專業與it方面是有些許關係的,但是沒有深入的往這方面涉及。在學校裡面學習過c語言和資料結構,但是我還沒有資格說我學過,一方面是因為學校教的真的真的是過於淺了,畢竟也是因為很多同學未來不會往這方面繼續學習或者工作,另一方面,我在學習這兩門課的時候也沒有很高的思...

動態規劃初步

基本原理 類似於遞迴解題,把問題丟給上一層來解決,找出狀態轉換方程即可。當然關鍵問題是如何定義遞迴陣列與找出狀態轉換方程。hello world 走樓梯 有n階樓梯,每次能走一步或兩步,請問有多少種走法。設f n 是n階樓梯不同的走法。則轉移到此狀態的方法有兩種,從n 1階樓梯走一步上來,或者從n ...

動態規劃初步

動態規劃的實質是通過多階段決策過程解決最優化問題,將每個問題分為若干個相互聯絡的階段,在它的每一階段都需要做出決策,這就是動態規劃與貪心演算法的區別,貪心演算法是以一種貪心規則進行最優運算,但往往得到的結果並不是問題的最優解,而動態規劃則不同,動態規劃是每一步都有乙個決策,保證了最優解是我們要找的整...