打劫房屋是典型的動態規劃問題,面試經常考,lintcode 上有 3 道題,總結一下做法。
打劫房屋 i
假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。
給定乙個非負整數列表,表示每個房子中存放的錢, 算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的情況下。
樣例給定[3, 8, 4]
, 返回8
. 思路
動態規範,初始狀態:
v[i] 表示第 i 個房子裡的錢,dp[i] 表示打劫到第 i 個房子時獲得的最大利潤 則 dp[0] = v[0],dp[1] = max(v[0], v[1])。
狀態轉移:
由於不能搶相鄰的房屋,則搶第 i 間房子就不能搶第 i - 1 間房子,就要比較一下搶這間是否划算。
所以 dp[i] = max(v[i] + dp[i - 2], dp[i - 1]);
由於 dp[i] 只跟 dp[i - 1] 和 dp[i - 2] 有關,所以每一步只要儲存這兩個值就行了。
class solution
return cur;
}};
打劫房屋 ii
在上次打劫完一條街道之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子圍成了乙個圈,這就意味著第一間房子和最後一間房子是挨著的。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。
給定乙個非負整數列表,表示每個房子中存放的錢, 算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的情況下。
思路和打劫房屋 i 比只是多了個首尾不能同時取的限制,所以可以用一樣的演算法先算一次取首不取尾的結果,再算一次不取首的結果,看看哪個大。
class solution
int sub(vector& nums, int start, int end)
return cur;
}};
打劫房屋
iii在上次打劫完一條街道之後和一圈房屋之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子組成的區域比較奇怪,聰明的竊賊考察地形之後,發現這次的地形是一顆二叉樹。與前兩次偷竊相似的是每個房子都存放著特定金額的錢。你面臨的唯一約束條件是:相鄰的房子裝著相互聯絡的防盜系統,且當相鄰的兩個房子同一天被打劫時,該系統會自動報警。
算一算,如果今晚去打劫,你最多可以得到多少錢,當然在不觸動報警裝置的情況下。
樣例
3
/ \2 3
\ \
3 1
竊賊最多能偷竊的金錢數是 3 + 3 + 1 = 7. 思路
這次把陣列換成了二叉樹,用層序的方式看二叉樹,則問題變成打劫了第 i 層 就不能打劫第 i - 1 層,也可以用打劫房屋 i 的方法來做了。
用遞迴的方式計算打劫到第 i 層的最大收益。
class solution
int sub(treenode* node, int& pre)
};
打劫房屋 III
在上次打劫完一條街道之後和一圈房屋之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子組成的區域比較奇怪,聰明的竊賊考察地形之後,發現這次的地形是一顆二叉樹。與前兩次偷竊相似的是每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且當相鄰的兩個房子同一天被打...
打劫房屋 II和打劫房屋 III
ii題目 在上次打劫完一條街道之後,竊賊又發現了乙個新的可以打劫的地方,但這次所有的房子圍成了乙個圈,這就意味著第一間房子和最後一間房子是挨著的。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負...
lintcode 打劫房屋
假設你是乙個專業的竊賊,準備沿著一條街打劫房屋。每個房子都存放著特定金額的錢。你面臨的唯一約束條件是 相鄰的房子裝著相互聯絡的防盜系統,且 當相鄰的兩個房子同一天被打劫時,該系統會自動報警。給定乙個非負整數列表,表示每個房子中存放的錢,算一算,如果今晚去打劫,你最多可以得到多少錢 在不觸動報警裝置的...