一)粉刷房子
剑指 Offer II 091. 粉刷房子 - 力扣(Leetcode)
1)这里面的横坐标代表的是房间的个数,纵坐标代表的是每一间房子所要进行涂刷颜料的价钱,况且相邻的两个房子之间是不可以涂颜色相同的颜料;
2)画出二维数组;
1)确定一个状态表示:这是一个线性的dp,确定状态表示要根据经验+题目要求
dp[i]表示粉刷到i位置的时候,所需要进行粉刷房子的最小花费,而最后一个位置可能涂红色,蓝色或者是绿色,所以我们将最后的状态进行划分
这个时候可以将题目给的数转化成二维数组,自己转化成二维数组,因为本身题目已经给定,粉刷房子的时候只有三种颜色
1)dp[i][0]表示:粉刷到i位置的时候(i位置表示第i间房子)
最后一个位置涂刷上红色,此时所需要的最小花费
2)dp[i][1]表示:粉刷到i位置的时候(i位置表示第i间房子)
最后一个位置涂刷上蓝色,此时所需要的最小花费
3)dp[i][2]表示:粉刷到i位置的时候(i位置表示第i间房子)
最后一个位置涂刷上绿色,此时所需要的最小花费
2)根据状态表示推导状态转移方程:选择最近的一步来进行划分问题
1)假设我i位置涂的颜色是红色,那么此时i位置也就是第i个房子花的钱数也是固定不变的,就是array[i][0];
2)那么我们只需要在0号位置到i-1位置找到花费最小的钱数即可,再加上当前位置涂的颜色的花费,那么此时花费的钱数就是i-1位置所花费的最小钱数+当前涂刷i位置为红色的时候所花费的钱数就等于当前在涂刷i位置涂刷红色所需要的最小钱数
3)假设当前位置i涂色涂成红色,那么只需要找i-1位置的涂色涂成绿色,或者是涂成蓝色的最小值即可,根据最后一个位置的粉刷房子的颜色来划分状态
dp[i][0]=Math.min(dp[i-1][1],dp[i-1][2])+array[i][0];
dp[i][1]=Math.min(dp[i-1][0],dp[i-1][2])+array[i][1];
dp[i][2]=Math.min(dp[i-1][0],dp[i-1][1])+array[i][2];
3)初始化,保证在进行计算dp[i][j]的时候数组下标不会发生越界,假设此时要进行填写dp[0][0]那么此时再进行计算dp的时候此时就会发生数组越界访问
在进行初始化的时候,可以进行加上虚拟节点这样的形式
1)虚拟节点里面的值,要保证后续填表时正确的
2)还需要保证下标的映射关系,如果要想要在dp表中找到原始矩阵的值,下标是需要统一减1的;
4)填表顺序:从上到下,从左到右
5)返回值:最后的返回值应该是要么涂上蓝色的最小花费,要么是涂上红色的最小花费,要么是涂上绿色的最小花费,照这三种情况的最小值
class Solution { public int minCost(int[][] array) { //1.创建一个dp表 int row=array.length; int col=array[0].length; int[][] dp=new int[row+1][col]; //2.进行填表 dp[0][0]=0; dp[0][1]=0; dp[0][1]=0; for(int i=1;i<row+1;i++){ //dp[i][0]表示粉刷到第i个房子且选择的颜色是红色的时候此时的最小花费 dp[i][0]=Math.min(dp[i-1][1],dp[i-1][2])+array[i-1][0]; //dp[i][1]表示粉刷到第i个房子且选择的的颜色是绿色的时候此时的最小花费 dp[i][1]=Math.min(dp[i-1][0],dp[i-1][2])+array[i-1][1]; //dp[i][2]表示粉刷到第i个房子且选择的颜色是蓝色的时候所需要的最小花费 dp[i][2]=Math.min(dp[i-1][1],dp[i-1][0])+array[i-1][2]; } //3.返回值 System.out.println(Arrays.deepToString(dp)); int data=Math.min(dp[row][0],dp[row][1]); return Math.min(dp[row][2],data); } }
二)最佳买卖股票时期含冷冻期:
题目要求:
1)可以在一天之内多次买卖一支股票
2)卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)
3)你必须在再一次买入股票之前卖出自己手中已经持有的股票
309. 最佳买卖股票时机含冷冻期 - 力扣(Leetcode)
1)定义一个状态表示:
以某一个位置为结尾,巴拉巴拉,以某一个位置为起点,巴拉巴拉
dp[i]表示第i天结束之后所能获得的最大利润
但是这个状态是可以继续细分的,假设当前处于第i天刚刚结束:
下面的三种状态都是在第i天结束之后,所处于的状态
可交易状态(卖出):把第i天结束之后,没有到i+1天的时候,将第i天的股票卖出以后所处于的状态,不持有任何股票,况且不在冷冻期;
买入状态:第i天结束之后,没有到第i+1天的时候,也就是说将第i填的股票卖出之后所处于的状态
冷冻期状态:第i天结束之后,没有到i+1天的时候,处于冷冻期,不能买卖股票,不持有任何股票,况且处于冷冻期中;
1)下面这种情况就是类似于说,假设第i天把股票卖了,那么第i天结束之后是出于冷冻期的状态,i天结束之后,如果是第i+2天如果不买任何股票,那么i+1天结束之后就处于卖出状态,况且不处于冷冻期,如果当天卖完了股票,那么当天结束之后会立即进入到冷冻期,那么下一天也买不了股票
2)dp[i][1]表示第i天结束之后处于冷冻期,那么这种情况一定是说第i天刚好把股票卖完了,第i+1天处于冷冻期,i+1天结束之后处于可交易状态,表示的就是虽然没有股票但是没有处于冷冻期;
3)假设i-1天结束之后处于冷冻期, 那么第i-1天一定是恰好将股票全部卖出,第i+1天处于冷冻期且不能买入任何股票
因为你在第i天结束的时候是存在着非常多的子状态的
1)可能在第i天结束的时候是处于一个买入状态,此时可能刚刚花钱买了第i天的股票;
2)可能是在第i天结束之后处于一个可交易的状态
经过第i天的时候,可能正好将自己持有的股票卖出;
3)要么是在第i天处于一个冷冻期的状态,此时用户已经把股票全部卖完了,第i-1天刚好把股票卖完
4)所以我们需要开辟一个二维数组,但是本质上这个题还是一个一维数组的线性问题
4.1)dp[i][0]表示在第i天结束的时候是处于买入状态,此时的最大利润
4.2)dp[i][1]表示在第i天结束的时候是处于可交易的状态,此时的最大利润
4.3)dp[i][2]表示在第i天结束的时候是出于冷冻期,此时