1. 程式人生 > >LeetCode——動態規劃

LeetCode——動態規劃

198 House Rober方法一)自頂向下的遞迴
class Solution {
private:
	//記錄    memo[i]表示——搶劫[i....nums.size()-1]所能獲取的最大收益
	vector<int> memo;
	//考慮去搶劫[index....nums.size()-1]這個範圍內所有的房子,返回值——搶劫[index....nums.size()-1]所能獲取的最大收益
	int tryRob(vector<int> &nums, int index)
	{
		if (index >= nums.size())
			return 0;
		if (memo[index] != -1)
			return memo[index];
		int res = 0;
		for (int i = index; i < nums.size(); i++)
		{
			res=max(res,nums[i] + tryRob(nums, i + 2));
			
		}
		memo[index] = res;
		return res;
	}

public:
	int rob(vector<int>& nums) {
		memo = vector<int>(nums.size(), -1);

		return tryRob(nums, 0);
	}
};
方法二)用自底向上的動態規劃
int rob(vector<int>& nums) {
		int n = nums.size();
		if (n == 0)
			return 0;

		// memo[i]表示——搶劫[i....n-1]所能獲取的最大收益
		vector<int> memo(n, -1);
		memo[n - 1] = nums[n - 1];
		for (int i = n - 2; i >= 0; i--)
		{
			for (int j = i; j < n; j++)
				memo[i] = max(memo[i], nums[j] +(j+2<n? memo[j + 2]:0));
		}
		return memo[0];
	}
213.House Robber這道題是前一道題的升級版
假設最後一個房間和第一個房間也是鄰居
class Solution {
private:
	
public:
	int rob(vector<int>& nums) {
		int n = nums.size();
		if (n == 0)
			return 0;
		if (n == 1)
			return nums[0];
		if (n == 2)
			return max(nums[0], nums[1]);

		// memo[i]表示——搶劫[i....n-1]所能獲取的最大收益
		//搶劫[1......n-1]
		vector<int> memo(n, -1);
		memo[n - 1] = nums[n - 1];
		for (int i = n - 2; i >= 1; i--)
		{
			for (int j = i; j < n; j++)
				memo[i] = max(memo[i], nums[j] +(j+2<n? memo[j + 2]:0));
		}
		//搶劫[0......n-2]
		vector<int> memo1(n, -1);
		memo1[n - 2] = nums[n - 2];
		for (int i = n - 3; i >= 0; i--)
		{
			for (int j = i; j < n-1; j++)
				memo1[i] = max(memo1[i], nums[j] + (j + 2<n-1 ? memo1[j + 2] : 0));
		}
		for (int i = 0; i < memo1.size(); i++)
			cout << memo1[i] << " ";
		cout << endl;
		cout << memo[1] << " " << memo1[0] << endl;
		return max(memo[1],memo1[0]);
	}
};