LeetCode 213. House Robber II

相比LeetCode 198. House Robber, 由于题目将整个房子变成了一个环形,我们在此就多增加了一维k, 用来专门标识是否取nums[0]. 

应用动态规划,构造数组dp[nums.size()][2][2], 对于dp[i][j][k], 

j=0时不取nums[i], j=1时取nums[i];

k=0时不取nums[0], k=1时取nums[0].

所以dp[i][0][0]即代表,在不去nums[i]和nums[0]的情况下,从nums[0, ..., i]中取得的最大值。


初始化:

// for stage-0

dp[0][1][1] = nums[0];

// for stage-1

dp[1][0][1] = nums[0];

dp[1][1][0] = nums[1];

注意到dp[0][0][1]和dp[1][1][1]都是不合法的特殊情况:如对于dp[1][1][1], 我们不可能同时取第0个和第1个元素(房子里的财产),所以我们将它的值赋为0, 不进行特殊的初始化。


代码:

class Solution 
{
public:
    int rob(vector<int>& nums) 
    {
    	if (nums.empty())
    	{
    		return 0;
    	} else if (nums.size() == 1)
    	{
    		return nums[0];
    	} else if (nums.size() == 2)
    	{
    		return max(nums[0], nums[1]);
    	}

    	// i: nums index, j: self taken or not, k: nums[0] taken or not
    	vector<vector<vector<int>>> dp(nums.size(), vector<vector<int>>(2, vector<int>(2, 0)));
    	// for stage-0
    	dp[0][1][1] = nums[0];
    	// for stage-1
    	dp[1][0][1] = nums[0];
    	dp[1][1][0] = nums[1];
    	for (size_t i = 2; i < nums.size(); ++ i)
    	{
    		dp[i][0][0] = max(dp[i-1][0][0], dp[i-1][1][0]);
    		dp[i][0][1] = max(dp[i-1][0][1], dp[i-1][1][1]);
    		dp[i][1][0] = dp[i-1][0][0] + nums[i];
    		dp[i][1][1] = dp[i-1][0][1] + nums[i];
    	}

    	return max(max(dp[nums.size()-1][0][0], dp[nums.size()-1][0][1]), 
    		dp[nums.size()-1][1][0]);
    }
};


你可能感兴趣的:(LeetCode,C++,dp,动态规划)