三、珠宝最高价值
他和上面的区别,就是他的内部是有自己的数字的,所以我们需要算出来可以拿的最大价值。
1.状态表示:
dp[i][j]:表示在ij位置,获取到的最高价值,
2.状态转移方程
dp[i][j]=MAX(dp[i-1][j],dp[i][j-1])+frame[i][j]; 左边和上边,看哪个更大,则说明有更高的价值,再加上当前这个地方的价值就构成了得到的最高价值。
3.初始化
初始化-还是防止越界问题,要出现虚拟节点
只有保证虚拟节点都是0,才不会导致,周围的受到影响,因为他是求的最大值,所以0不会收到影响
4.填表的顺序,从左到右,从上到下。
5.返回值dp[i][j]
class Solution { public int jewelleryValue(int[][] frame) { int m=frame.length,n=frame[0].length; int [][]dp=new int[m+1][n+1]; for(int i=1;i<m+1;i++){ for(int j=1; j<n+1;j++){ dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j])+frame[i-1][j-1]; } } return dp[m][n]; } }
四、下降路径最小和
1.状态表示
用经验得到
dp[i][j]以i,j位置结尾的下降路径最小和
2。状态转移方程(这里说一下,你的状态方程是根据你的选择的点想法去处理的。
dp[i][j]=min(dp[i-1][j],dp[i-1][j+1],dp[i-1][j+2])+m[i][j] (这个位置是最左边)
dp[i][j]=min(dp[i-1][j],dp[i-1][j],dp[i-1][j+1])+m[i][j] (这个就是中间的)
3.初始化
初始化是根据你的状态转移方程决定的
假如说你的这个最左边(红色的是添加的虚拟节点)
中间的话就是这样需要
填表顺序:从上到下,从左到右
返回值:min(dp[i][j-1],dp[i][j],dp[j+1])
class Solution { public int minFallingPathSum(int[][] matrix) { int m=matrix.length,n=matrix[0].length; int [][]dp=new int[m+1][n+2]; for(int i=1;i<m+1;i++){ dp[i][0]=Integer.MAX_VALUE; dp[i][n+1]=Integer.MAX_VALUE; } for(int i=1;i<m+1;i++){ for(int j=1;j<n+1;j++){ dp[i][j]=Math.min(dp[i-1][j-1],Math.min(dp[i-1][j],dp[i-1][j+1]))+matrix[i-1][j-1]; } } //要学会给无穷大的值 int ret=Integer.MAX_VALUE; for(int j=1;j<n+1;j++){ ret=Math.min(ret,dp[m][j]); } return ret; } }
最后总结
刷半天题,我感觉动态规划就像是说,你玩超级马里奥,从你通关的角度看,假如说往回看,你发现你通关了,其中你发现掉进水管子也能通关,但是掉进水管子是特殊情况,怎么说呢,就想是,你看到特殊情况了,但是他也是你的计划中的一员