題目:房間有金子, 價值各不同。 連偷會報警, 如何賺大錢?
輸入:houses = {3, 5, 2, 10}
解釋:有四間屋子,金子的價值各是3、5、2、10 偷的時候,不能偷連續的房間,
比如,偷了3,就不能偷5;偷了5就不能偷3和2
輸出:15
思路分析:可做如圖1所示的過程分析,同種顏色虛線框爲相同子問題。
代碼實現:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int GetMemo(int id, vector<int>& memo, vector<int>& houses)
{
if (id >= memo.size())
return 0;
if (memo[id] == -1) {
int selectFirstElement = houses[id] + GetMemo(id + 2,memo,houses);
int unselectFirstElement = GetMemo(id + 1, memo, houses);
memo[id] = max(selectFirstElement, unselectFirstElement);
}
return memo[id];
}
int GetGlod(vector<int>& houses)
{
vector<int> memo(houses.size(), -1); //memo是從第id房間到最後一房間能偷到的最大金子價值
return GetMemo(0, memo, houses);
}
int main()
{
vector<int> houses({ 3,5,2,10 });
cout << GetGlod(houses) << endl;
return 0;
}
擴展問題:如果是環怎麼辦,如果是樹怎麼辦?
如果是環的話,只需要對第一個房間做出分析後便可轉化爲兩個線性結構:(如圖2)
樹和圖結構同理。
總結:
備忘模型:
1.畫解空間樹(tree)
2.解空間樹的節點表示(node)
3.重複節點(duplicate)
4.推理(infer)
5.自下到上進行演繹(若利用演繹模型做)
箴言錄:
天下難事,必作於易;天下大事,必作於細。