你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
解题思路:对于每一间房屋有两种状态头还是不偷 ,第i间房屋头取得最大金额可以有i-1个房屋和i-2个房屋推导出来。第i个房屋有梁总状态,偷和不偷,如果偷,s说明他的前一个没有偷偷,它的最大金额等于dp[i-2]+这建房子头取得,如果不偷,说明前哪一个投过了,最大金额就是dp[i-1]
代码实现:
class Solution {
public int rob(int[] nums) {
if(nums.length==1) return nums[0];
//打家劫舍,
//根据题目的意思 ,每一次偷取的钱币数量其实是根据上一个房间是否偷取推到的,不妨使用动态规划五部曲来分析一下
//1,dp数组含义
//下标为i的房间偷盗的最大金额为dp[i]
int[] dp=new int[nums.length];
//2,确定递推公式
//假设当前位于i这个房间,
//如果i偷,则有dp[i]=dp[i-2]+nums[i]
//如果i不偷,则有dp[i]=dp[i-1];
//则递推公式i就是i偷取和不偷取的最大值
//3,dp数组初始化
//首先假设偷取第0个房间
dp[0]=nums[0];
//是否偷取第1个房间,取决于第0个房间的金额和第1个
//房间的金额谁更大
dp[1]=Math.max(nums[0],nums[1]);
//4,开始循环遍历,从那个下标为2的房间开始遍历
for(int i=2;i<nums.length;i++){
dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.length-1];
}
}
打家劫舍2,3核心思路就是1,只不过实现方式有所区别。
给定一个数组 prices
,它的第 i
个元素 prices[i]
表示一支给定股票第 i
天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
代码实现,注解中包含解析:
class Solution {
public int maxProfit(int[] prices) {
//使用二维dp数组表示买卖股票的状态
//1,dp数组含义,dp[i][0]表示第i天持有股票的所得最多现金,他有肯能是负数
//dp[i][1]表示第i天不持有股票所得最多现金
//有可能是前面的天数,也有可能是i这一天
int[][] dp=new int[prices.length][2];
//2,确认递推公式
//在第i天,不出售持有股票的最大利润 dp[i-1][0]
//在第i天,出手后股票的最大利润 dp[i]
//3,初始化
dp[0][0]=-1*prices[0];
dp[0][1]=0;
for(int i=1;i<prices.length;i++){
//第i天持有股票所得现金等于
//前一天持有股票现金和未持有股票,买入的现金的最大值
dp[i][0]=Math.max(dp[i-1][0],-1*prices[i]);
//第几天未持有股票也是如此
dp[i][1]=Math.max(dp[i-1][1],dp[i][0]+prices[i]);
}
return dp[prices.length-1][1];
}
}
By-三条直线围墙