算法分析与设计课程作业第十七周#1#2

算法分析与设计课程作业第十七周#1#2

这周选了两道House Robber题,是上周做的其中一道题的两个变种,其实这两道题都比上周做的那道简单,但都揭示一个思路,就是分类讨论,对某一个元素分选与不选的情况讨论。

198. House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
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.

思路

就是对其中某一家,如果选,则其相邻的前面一家必定不能选,总抢劫量与其相邻的前面一家无关,如果选,则总抢劫量与该家无关。
状态转移式:
dp[i]表示从0到i能抢劫的最高金额。
dp[i] = max(dp[i-1], dp[i-2] + nums[i])

代码

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

213. House Robber II

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.

思路

这道题将街道连成一个环,使第一间房子与最后一间房子不能同时抢,使上题的计算方法失去终止条件,看似困难很多。但其实还是分类讨论就好了。总共就两种分类,就是第一间房选与第一间房不选,就可以退化成用上一题的算法能解决的问题了。

代码

class Solution {
public:
    int rob(vector<int>& nums) {
        int size = nums.size();
        vector<int> dp(size, 0);
        if(size == 0) return 0;
        dp[0] = nums[0];
        if(size == 1) return dp[0];
        dp[1] = nums[0];
        for(int i = 2; i < size-1; i++){
            dp[i] = max(dp[i-1], dp[i-2] + nums[i]);
        }
        int choosefirst = dp[size-2];
        dp[0] = 0;
        dp[1] = nums[1];
        for(int i = 2; i < size; i++){
            dp[i] = max(dp[i-1], dp[i-2] + nums[i]);
        }
        int chooselast = dp[size-1];
        return max(choosefirst, chooselast);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值