62. 不同路径

public int uniquePaths(int m, int n) {int[][] dp = new int[m][n];for (int i = 0; i < m; i++) {dp[i][0] = 1;}for (int i = 0; i < n; i++) {dp[0][i] = 1;}for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {dp[i][j] = dp[i - 1][j] + dp[i][j - 1];}}return dp[m - 1][n - 1];}
63. 不同路径 II

- 确定dp数组(dp table)以及下标的含义
dp[i][j] :表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。
- 确定递推公式
递推公式和62.不同路径一样,dp[i][j] = dp[i - 1][j] + dp[i][j - 1]。 但这里需要注意一点,因为有了障碍,(i, j)如果就是障碍的话应该就保持初始状态(初始状态为0)。
- dp数组如何初始化
如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。
- 确定遍历顺序
从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。
public int uniquePathsWithObstacles(int[][] obstacleGrid) {if(obstacleGrid==null||obstacleGrid.length==0) return 0;if(obstacleGrid[0][0]==1) return 0;int m=obstacleGrid.length,n=obstacleGrid[0].length;int[][] dp=new int[m][n];dp[0][0]=1;for(int i=1;i<n;i++){if(dp[0][i-1]==1&&obstacleGrid[0][i]==0){dp[0][i]=1;}}for(int i=1;i<m;i++){if(dp[i-1][0]==1&&obstacleGrid[i][0]==0){dp[i][0]=1;}}for(int i=1;i<m;i++){for(int j=1;j<n;j++){if(obstacleGrid[i][j]==1){dp[i][j]=0;}else{dp[i][j]=dp[i-1][j]+dp[i][j-1];}}}return dp[m-1][n-1];}
343. 整数拆分

- 确定dp数组(dp table)以及下标的含义
dp[i]:表示第i个数可以获得的最大乘积。
- 确定递推公式
因为n可以拆分成至少两个正整数,令j 是第一个被拆分的数字,则剩下的部分为(i -j ), (i-j)可以选择继续拆分,或者不拆分
- dp数组如何初始化
如果(i, 0) 这条边有了障碍之后,障碍之后(包括障碍)都是走不到的位置了,所以障碍之后的dp[i][0]应该还是初始值0。
- 确定遍历顺序
从递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导dp[i][j]的时候,dp[i - 1][j] 和 dp[i][j - 1]一定是有数值。
public int integerBreak(int n) {int[] dp = new int[n + 1];for (int i = 2; i <= n; i++) {int curMax = 1;for (int j = 1; j < i; j++) {curMax = Math.max(curMax, Math.max(j * (i - j), j * dp[i - j]));}dp[i] = curMax;}return dp[n];}
