码迷,mamicode.com
首页 > 其他好文 > 详细

解题思路:house robber i && ii && iii

时间:2017-03-15 14:42:04      阅读:260      评论:0      收藏:0      [点我收藏+]

标签:连续   隐藏   不能   dp2   连接   发家致富   log   解题思路   一点   

这系列题的背景:有个小偷要偷钱,每个屋内都有一定数额的钱,小偷要发家致富在北京买房的话势必要把所有屋子的钱都偷了,但是屋子之内装了警报器,在一定条件下会触发朝阳群众的电话,所以小偷必须聪明一点,才能保证偷到的钱最多。

 

问题i:这些屋子排成一排,连续两家失窃就会触发朝阳群众电话

问题ii:这些屋子两成一个圈(四合院既视感),连续两家失窃就会触发朝阳群众电话

问题iii:这些屋子组成一棵树,有连接的两个节点同时失窃就会触发朝阳群众电话

 

i: 思路:一道典型的dp问题,dp[i]表示在小偷路过第i间房子后可以获得的最大收益。小偷这个时候有两个选择,to steal or not to steal, that is a  problem。考虑到会报警的情况,如果第i-1间房子小偷没下手的话,那么 dp[i] = dp[i-1]+nums[i];如果第i-1间的房子小偷下手的话,那么dp[i] = dp[i-1],如果小偷想把自己的利益最大化,比如会有 dp[i] = max(dp[i-1]+nums[i],dp[i-1]),不对啊,这个怎么看都是前者比较大吧?其实还有个隐藏的细节在这里,如果第i-1间房子没有下手的话, dp[i-1] = dp[i-2]。所以dp的状态方程就变成dp[i] = max(dp[i-2]+nums[i],dp[i-1])。由于咱们实际上只需要3个变量就足以记录dp信息,所以就不用数组记录dp信息啦。

        
int size = nums.size();
     if(size == 0) return 0; if(size == 1) return nums[0]; if(size == 2) return max(nums[0],nums[1]); int s1 = nums[0],s2 = max(nums[0],nums[1]),s3; for(int i = 2;i<size;i++){ s3 = max(s2,s1+nums[i]); s1 = s2;s2 = s3; } return s3;

ii: 思路:给的仍然是一个数组,只是第一间房子和最后一间房子不能同时下手,其实仍然是问题i的变形而已,只要不同时取到第一间和最后一间就行啦。所以有两种情况,一个是我不考虑最后一间,即考虑从第1到第n-1间房子;另一个是我不考虑第一间,即考虑从第2到第n间的情况。然后比较这两种情况。

        int size = nums.size();
        if(size == 0) return 0;
        if(size == 1) return nums[0];
        if(size == 2) return max(nums[0],nums[1]);
        if(size == 3) return max(max(nums[0],nums[1]),nums[2]);
        vector<int> dp(size-1,0),dp2(size-1,0);
        int s1 = nums[0],s3 = nums[1],s2 = max(nums[1],nums[2]),s4 =  max(nums[2],nums[1]), s5,s6;

        
        for(int i = 2;i<size-1;i++){
            s5 = max(s1,s2+nums[i]);
            s6 = max(s3,s4+nums[i+1]);
            s1 = s2; s2 = s5;
            s3 = s4; s4 = s6;
        }
        
        return max(s5,s6);    

 

iii:这道题的画风和i&&ii不太一样,感觉考察的是树的问题。我AC的解法效率不高,不过便于理解,用一个flag辅助判断,如果flag为1表示当前节点不能偷;如果flag为0,当前节点可以偷,但是小偷有两种选择,to steal or not to steal,这取决了会不会让利益最大化。所以用一个递归解决了。

class Solution {
public:
    int helper(TreeNode* root,bool flag){
        if(!root) return 0;
        if(flag) return helper(root->left,0)+helper(root->right,0);
        else return max(root->val+helper(root->left,1)+helper(root->right,1),helper(root->left,0)+helper(root->right,0));
    }
    int rob(TreeNode* root) {
        return helper(root,0);
    }
};

  

解题思路:house robber i && ii && iii

标签:连续   隐藏   不能   dp2   连接   发家致富   log   解题思路   一点   

原文地址:http://www.cnblogs.com/unclelin/p/6553670.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!