#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
/*
问题:
Note: This is an extension of House Robber.
After robbing those houses on that street, the thief has found himself a new place for his thievery so that he will not get too much attention. This time, all houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, the security system for these houses remain the same as for those in the previous street.
Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
分析:此题修改题目为环,确实可以增加获取的财富,但要明确如果已经获取过的人家,就需要被设置删除标记位,
删除后的还是否默认相邻? 因为默认相邻,如果遍历一遍返回回来发现比如最后一户和第一户都被遍历了,
说明不符合条件,这个看上去和环相关的应该是一个回溯问题
举例:例如下图5户人家,顺时针开始,如果初始从4开始,下一户就是1
1
2 3
4 2
也就是说选定第一个结点,最后一个节点不能访问。我们遍历所有节点作为第一个节点,求出倒数第二个结点的最大值即可
设dp[i]表示A[0...i]的最大财富
dp[i]=max{dp[i-1] , dp[j] + A[i]},j属于[0, i-2]
dp[0]=A[0],dp[1]=A[1],
所求目标dp[n-2],n为A的长度
注意边界:只有1户,可以访问;只有2户,因为彼此相连,选择其中大的
对于选择任意点作为起始点,当遍历到某个点为n-1的时候,设置下一次遍历的时候i=0
i = beg - 2,处理完后,结束遍历
输入:
5(结点个数)
4 2 1 3 2
4
2 1 1 2
1
1
2
1 2
3
0 0 0
输出:
7
3
1
2
0
关键:
1 参考:https://leetcode.com/problems/house-robber-ii/?tab=Solutions
动态规划方程: dp[i]=max{dp[i-1] , dp[i-2] + A[i]}
可以用pre代替dp[i-1],用cur代替dp[i],然后更新pre=cur,temp=max(pre,cur),cur=temp
另外有了环之后:等于遍历0到n-2,或者1到n-1,为什么2到n-1,再到0不需要考虑,3到n-1到1不需要考虑
因为只有第0个房间与最后第n-1个房间相连,只存在遍历第0个房间与否的问题
2 报错:Input:[0,0,0]
Output:-2147483648
Expected:0
原因:初始设定的最大值为0。而不是INT_MIN。3个元素就应该返回三个中最大的
*/
class Solution {
public:
int robHelper(vector<int>& nums , int begin , int end)
{
int pLast = 0;
int ppLast = 0;
for(int i = begin ; i <= end; i++)
{
int temp = pLast;
pLast = max(pLast , ppLast + nums.at(i));
ppLast = temp;
}
return pLast;//最后一次求的结果,参见pLast = max(pLast , ppLast + nums.at(i));
}
int rob(vector<int>& nums) {
if(nums.empty() )
{
return 0;
}
if(1 == nums.size())
{
return nums.at(0);
}
if(2 == nums.size())
{
return max(nums.at(0) , nums.at(1));
}
int n = nums.size();
return max( robHelper(nums , 0 , n-2) , robHelper(nums , 1 , n - 1) );
}
};
void process()
{
vector<int> nums;
int value;
int num;
Solution solution;
while(cin >> num )
{
nums.clear();
for(int i = 0 ; i < num ; i++)
{
cin >> value;
nums.push_back(value);
}
int answer = solution.rob(nums);
cout << answer << endl;
}
}
int main(int argc , char* argv[])
{
process();
getchar();
return 0;
}