动态规划刷题(4)

一)粉刷房子

剑指 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天结束的时候是出于冷冻期,此时

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值