阿里20.3.25笔试题第一题 (动态规划,类似于路径搜索思想)
题目描述
给定一个行数为3,列数为col的矩阵B,比如
5 10 5 4 4
1 7 8 4 0
3 4 9 0 3
从每一列中选择一个数,得到一个一行col列的一维数组,求该一维数组中每相邻两个数之差的绝对值的累加和的最小值
比如这里就是5 7 5 4 4,所以输出是5
输入描述
四行输入
第一行输入为数组的列数n;
第二至四行输入一个3*col的矩阵a,每行输入col个正整数。
输出描述
一行一个正整数表示答案
思路分析
- 首先是输入的部分,首先接收输入一个正整数n, 再建立一个二维数组来存放输入矩阵,行数为3,列数为n。双层循环遍历用输入给数组赋值。
- 这题的思路首先想到类似于路径搜索,在矩阵中从最左列开始选择一条路径,一列一列地走到最右列(其中每一列只能走一次),最终的结果是求这条路径,使其满足路径上的元素相邻元素的差值的绝对值累加和最小。因此想到用动态规划。
- 选择二维数组来存储元素 (i,j) 的状态dp[i][j],定义为选择元素 (i,j) 作为路径的终点,此时对应的结果为res,因此最终的结果应该为遍历i=1,2,3 res=Math.min(dp[i][col-1]) ;
- 状态转移方程:
点(i,j)的状态dp[i][j]应该等于路径中前一个点(即为前一列所选择的数) (k,j-1)再加上点(i,j)与(k,j-1)的差值的绝对值,因此
dp[i][j]=Math.abs(array[i][j]-array[k][j-1])+dp[k][j-1]);
此处,由于本列选择的数是第i行,但前一列选择的数不一定是哪一行,记为第k行,因此遍历k=0,1,2, 选择Math.abs(array[i][j]-array[k][j-1])+dp[k][j-1]) 的最小值。
- 最终结果返回遍历i 获得的最小值dp[i][col-1]。
易错点
- 二维数组循环输入赋值,先遍历行,再遍历列
- 动态规划的部分,此题是整列的规划,先遍历列,在固定第j列的时候遍历了行i,在固定了(i,j)的时候再遍历前一点的k。因此,内外循环是先j 其次i 最后k,顺序不能改变。
//阿里20.3.25笔试题第一题 (动态规划,类似于路径搜索)
import java.util.Scanner;
import java.util.Arrays;
public class Main5 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int col= in.nextInt();
int[][] array = new int[3][col];
//二维数组的输入
for (int i = 0; i<3; i++) {//此处i与j调换位置也会出错
for (int j=0;j<col;j++) {
array[i][j] = in.nextInt();
}
}
int [][] dp=new int[3][col];//动态规划 整列规划
for (int i = 0; i < 3; i++) {
Arrays.fill(dp[i],0);//初始化
dp[i][0] = 0;
}
for(int j=1;j<col;j++)//此处注意若i与j调换位置,就不对了
{
for(int i=0;i<3;i++)
{
dp[i][j]=Math.abs(array[i][j]-array[0][j-1])+dp[0][j-1];
for(int k=1;k<3;k++)
{
dp[i][j]=Math.min(dp[i][j],Math.abs(array[i][j]-array[k][j-1])+dp[k][j-1]);
/* dp[i][j]=Math.min(Math.abs(array[i][j]-array[0][j-1])+dp[0][j-1],
Math.min(Math.abs(array[i][j]-array[1][j-1])+dp[1][j-1],
Math.abs(array[i][j]-array[2][j-1])+dp[2][j-1]));*/
}
}
}
int res=dp[0][col-1];
for(int i=0;i<3;i++)
{
res=Math.min(res,dp[i][col-1]);
}
// int res=Math.min(dp[0][col-1],Math.min(dp[1][col-1],dp[2][col-1]));
System.out.println(res);
}
}
(PS: 笔试时有了思路,但是一方面卡在了输入输出,一方面卡在了当前点的前一点(k,j) 这里的k是遍历求最小值来确定 ,所以还是要多做动态规划的题呀~)