动态规划习题--九章算法第五、六章习题
1.Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
The minimum path sum from top to bottom is 11
(i.e., 2 + 3 + 5 + 1 = 11).
//如果最终最优路径过该点,从起点到该点的路径中,一定是最优的那条入选最优路径;但是从起点到该点的最优路径不一定是局部最优路径,有可能比同阶段的相邻点大 public class Solution { public int minimumTotal(List<List<Integer>> triangle) { int n = triangle.size(); int[][] f = new int[n][n]; //因为每步只能走临近的数字,因此横向最长也是跟行数相等 //初始化 for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ f[i][j]=Integer.MAX_VALUE; } } f[0][0]=triangle.get(0).get(0); //让f[i][j]代表从起点到i,j点的最小路径 //最小路径和f[0][n-1]~f[n-1][n-1]的最小值 for(int i =1;i<n;i++){ for(int j=0;j<=i;j++){ if(j==0) f[i][j]=f[i-1][j]+triangle.get(i).get(j); else f[i][j]=Math.min(f[i-1][j],f[i-1][j-1])+triangle.get(i).get(j); } } int min=Integer.MAX_VALUE; for(int i =0;i<n;i++){ if(f[n-1][i]<min) min=f[n-1][i]; } return min; } }
精简空间度的版本:由于f[i][j]只与f[i-1][j]和f[i-1][j-1]有关,即仅与上一行状态有关因此可仅申请2行的空间,i的处理上%2就好了。如果与前2行有关就%3,....以此类推
1 public class Solution { 2 public int minimumTotal(List<List<Integer>> triangle) { 3 int n = triangle.size(); 4 int[][] f = new int[2][n]; //因为每步只能走临近的数字,因此横向最长也是跟行数相等 5 6 //初始化 7 for(int i=0;i<n;i++){ 8 for(int j=0;j<n;j++){ 9 f[i%2][j]=Integer.MAX_VALUE; 10 } 11 } 12 f[0][0]=triangle.get(0).get(0); 13 //让f[i][j]代表从起点到i,j点的最小路径 14 //最小路径和f[0][n-1]~f[n-1][n-1]的最小值 15 for(int i =1;i<n;i++){ 16 for(int j=0;j<=i;j++){ 17 if(j==0) 18 f[i%2][j]=f[(i-1)%2][j]+triangle.get(i).get(j); 19 else 20 f[i%2][j]=Math.min(f[(i-1)%2][j],f[(i-1)%2][j-1])+triangle.get(i).get(j); 21 } 22 } 23 int min=Integer.MAX_VALUE; 24 for(int i =0;i<n;i++){ 25 if(f[(n-1)%2][i]<min) 26 min=f[(n-1)%2][i]; 27 } 28 return min; 29 } 30 }
//如果最终最优路径过该点,从起点到该点的路径中,一定是最优的那条入选最优路径;但是从起点到该点的最优路径不一定是局部最优路径,有可能比同阶段的相邻点大
public class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int n = triangle.size();
int[][] f = new int[2][n]; //因为每步只能走临近的数字,因此横向最长也是跟行数相等
//初始化
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
f[i%2][j]=Integer.MAX_VALUE;
}
}
f[0][0]=triangle.get(0).get(0);
//让f[i][j]代表从起点到i,j点的最小路径
//最小路径和f[0][n-1]~f[n-1][n-1]的最小值
for(int i =1;i<n;i++){
for(int j=0;j<=i;j++){
if(j==0)
f[i%2][j]=f[(i-1)%2][j]+triangle.get(i).get(j);
else
f[i%2][j]=Math.min(f[(i-1)%2][j],f[(i-1)%2][j-1])+triangle.get(i).get(j);
}
}
int min=Integer.MAX_VALUE;
for(int i =0;i<n;i++){
if(f[(n-1)%2][i]<min)
min=f[(n-1)%2][i];
}
return min;
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。