小菜找实习——阿里3.25场笔试第一题(矩阵数组最小差值和)
程序员文章站
2022-07-10 21:21:37
...
明天晚上就要笔试了,又有新的原题来参考练手了,这道题如果不知道viterbi算法可能通过dp有点难做出来。
所以说学习是永无止境的hhh!
图源自牛客论坛上(话说他们是怎么截图的,难道这样不算作弊吗,不太懂笔试的规则)
输入描述
4
5 9 5 4 4
4 7 4 10 3
2 10 9 2 3
输出描述
5
确定状态
Viterbi算法是说每到一个状态就记录下到当前状态的最值,然后以此为基准向后推进(因此就是动态规划的思想)
dp[i][j]表示走到第i行第j列的最小值
状态转移方程
dp[i][j] = min{ dp[k][j-1] +abs{matrix[i][j]-matrix[k][j-1]},dp[i][j]} {k=0,1,2}
初始状态和边界条件
dp[k][0] = 0 (第一列的差值为0)
计算顺序
dp[0][1] dp[1][1] dp[2][1]
....
dp[0][n-1] dp[1][n-1] dp[2][n-1]
最终返回值:min{dp[0][n-1] dp[1][n-1] dp[2][n-1]}
代码
public static void solve(int [][]matrix){
int m=matrix.length;
int n=matrix[0].length;
int[][]dp=new int[m][n];//动态规划,表示到这里的最小差值
for (int j=1;j<n;j++){//第一列差值为0,默认就是,所以不用再赋值了
for (int i=0;i<m;i++){
dp[i][j]=Integer.MAX_VALUE;
for(int k=0;k<m;k++){
dp[i][j]=Math.min(dp[k][j-1]+Math.abs(matrix[i][j]-matrix[k][j-1]),dp[i][j]);
}
}
}
int min=Integer.MAX_VALUE;
for(int i=0;i<m;i++){
min=Math.min(min,dp[i][n-1]);
}
System.out.println(min);
}