最近學習動態規劃有點吃力,感覺這個東西雖然說是有套路的,但是剛開始的時候還是覺得難。現在網上也有很多講動態規劃的原理以及做法的,我就不多說了,主要還是以例子來記錄一下最近的心得。
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,
如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
示例1:
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
示例2:
輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接著偷竊 5 號房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。
放上原題鏈結
對於這道題目,是乙個明顯的動態規劃的題目,後面的決策不會影響到前面的決策,前面的決策怎麼得來的這個並不重要。
首先設計狀態,標準的我們可以定義dp[i][j];i表示第i家,j只有2個狀態,0表示不偷第i家,1表示偷第i家;
接下來寫出狀態狀態轉移方程;
(1)dp[i][0]表示不偷第i家,那麼i-1家可能是偷了,也可能是沒偷,所以需要判斷偷與不偷哪乙個獲得的金額是最大的;
所以dp[i][0] = math.max(dp[i-1][0],dp[i-1][1]);
(2)dp[i][1]表示偷了第i家,那麼第i-1家一定是沒偷的,所以直接加上今天偷的金額就可以;
所以dp[i][1] = dp[i-1][0] + nums[i];最後就是定義初始狀態啦~顯然每天偷與不偷都是取決於前一天的狀態,所以定義dp[0][0] = 0,dp[0][1] = nums[0];
class
solution
if(nums.length ==1)
int len = nums.length;
//dp[i][0]表示不偷第i家使用者所獲得的最大金額
//dp[i][1]表示偷了第i家使用者所獲得的最大金額
int[
] dp =
newint[2
][2]
; dp[0]
[0]=
0;dp[0]
[1]= nums[0]
;for
(int i=
1;i)return math.
max(dp[
(len-1)
&1][
0],dp[
(len-1)
&1][
1]);
}}
當然這道題還有另外一種解法:
class
solution
if(nums.length ==1)
int len = nums.length;
//dp[i]有兩種狀態
//1.偷了第i家,那麼第i-1家一定沒偷,但是第i-1家又包括了偷了的狀態,所以應該從i-2開始;
//2.沒偷第i家,那麼就直接從i-1狀態轉移過來;
int[
] dp =
newint[3
];dp[0]
= nums[0]
;;dp[1]
= math.
max(nums[0]
,nums[1]
);for(
int i=
2;i)return dp[
(len-1)
%3];
}}
這道題目和leetcode上的另外一道題目按摩師類似,大家也可以去看一看練習一下。
給定乙個整數陣列 nums ,找到乙個具有最大和的連續子陣列(子陣列最少包含乙個元素),返回其最大和。
輸入: [-2,1,-3,4,-1,2,1,-5,4],
輸出: 6
解釋: 連續子陣列 [4,-1,2,1] 的和最大,為 6。
這道題我剛開始的寫的時候還是比較繞的,簡單來說要求最大子串行和,那第一步我們就定義乙個最大子串行和sum,在每次遍歷的時候都獲取最大的那個值max_value;
如果sum>0,說明這個結果對我們有增益效果,保留;
但是sum<0,說明這個結果沒有增益效果,應當直接剔除;
每次比較sum和max_value的值的大小即可。
class
solution
int maxsum = nums[0]
;int sum =0;
for(
int i=
0;i)else
maxsum = math.
max(sum,maxsum);}
return maxsum;
}}
動態規劃小結
現在做一下動態規劃的小結 1.揹包問題 這是一類超級經典很基礎的動態規劃,好多動態規劃題目都能用揹包的方法寫出或者是揹包的變形.這些在揹包九講中說的很清楚 鏈結 這是網上我隨便找的乙個講的比較全的部落格 這些揹包問題給我的乙個啟發就是 轉換,通過一系列的操作,轉換為01揹包 揹包給我的感受 很大一部...
動態規劃小結
1.最長上公升子串行問題 給出乙個由n個數組成的序列x 1.n 找出它的最長單調上公升子串行。即求最大的m和a1,a2 am,使得a12.動態規劃求解思路分析 o n 2 經典的o n 2 的動態規劃演算法,設a i 表示序列中的第i個數,f i 表示從1到i這一段中以i結尾的最長上公升子串行的長度...
動態規劃小結
近期覺得動態規劃的題目一直不能夠很好的理解,自己也不能很好的掌握,因此就做了一定量的練習,使得自己能夠掌握這一類題目的思路。動態規劃在維基百科的定義為 一種在數學 管理科學 電腦科學 經濟學和生物資訊學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。動態規劃的思想為 若要解決乙...