2020.3.25阿里笔试题

1:题目描述

作者:海森堡CSQ
链接:https://www.nowcoder.com/discuss/391530?type=post&order=time&pos=&page=1
来源:牛客网

第一题,给定一个数组n,比如
5 10 5 4 4
1  7  8 4 0
3  4  9 0 3
从每一列选择一个数,求出后一列减去前一列的绝对值的和的最小值
比如这里就是5 7 5 4 4,所以输出是5

2:解题思路

  本地我们经过分析,可以明确发现本列最短路径和下一列最短路径之间有很大的关系,我们可以使用动态规划的思想解决这个问题;

  1. 状态定义:如何定义出可以找到转移方程的状态,是这个问题的关键。我们分析发现相邻两列之间的最短路径之间关系如下;假设dp[0],dp[1]和dp[2]分别代表从第一列到达此列的第0行数,第1行数,第2行数的最短路径,那么到达后一列的第0行,第1行和第2行的最短路径和dp[0],dp[1],dp[2]有什么关系尼?显然假设后一列第0行,第1行,第2行的最短路径分别为next[0],next[1],next[2],第0行数据为 n[0],第1行数据为 n[1],第2行数据为 n[2],则有,next[0] = min(abs(dp[0]-n[0]),abs(dp[1]-n[0]),abs(dp[2]-n[0]))。这是什么含义尼?就是本列的三行分别到n[0]处的路径中最短一个就为最短一个。所以定义状态dp[0],dp[1],dp[2]分别待变到达本列第0行,第1行,第2行的最短路径。
  2. 转移方程:正如上面个描述的那样
    1. next[0] = min(abs(dp[0]-n[0]),abs(dp[1]-n[0]),abs(dp[2]-n[0]))。
    2. next[1] = min(abs(dp[0]-n[1]),abs(dp[1]-n[1]),abs(dp[2]-n[1]))。
    3. next[2] = min(abs(dp[0]-n[2]),abs(dp[1]-n[2]),abs(dp[2]-n[2]))。
  3. 暂存结果:使用dp[0],dp[1],dp[2]来保存上面的next结果,为后面的循环做准备。

3:代码示例

package NiuKe;

/**
 * @author :dazhu
 * @date :Created in 2020/3/20 18:50
 * @description:AC测试
 * @modified By:
 * @version: $
 */
import java.util.*;
public class Main {
    static int n;
    static int[][] array;
    static int postTemp = 0;//下一列选择地值
    static int curTemp = 0;//当前列选择地值
    static int resultSum = 0;//当前和
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        array = new int[3][n];
        for(int i = 0; i < 3; i++){
            for(int j = 0; j < n; j++){
                array[i][j] = sc.nextInt();
            }
        }

        System.out.println(getMin(array));

    }

    public static int getMin(int[][]array){
        if(array[0].length ==1){
            return 0;
        }
        int[] dp = new int[]{0,0,0};
        int[] temp = new int[]{0,0,0};


        //1 2 3 4 5
        //2 3 4 5 6
        //23 45 12 5 2
        for(int i=1;i<n;i++){//外循环控制列数
            for(int j=0;j<3;j++){//内训还控制行数
                //按照状态转移方程,更新的新的最短路径
                temp[j] = Math.min(Math.min(Math.abs(array[j][i] - array[0][i-1]) + dp[0],
                                    Math.abs(array[j][i] - array[1][i-1]) + dp[1]),
                                    Math.abs(array[j][i] - array[2][i-1]) + dp[2]);
            }
            //寄存结果
            for(int k=0;k<3;k++){
                dp[k] = temp[k];
            }
        }
        return Math.min(Math.min(dp[0], dp[1]),dp[2]);
    }
}

猜你喜欢

转载自www.cnblogs.com/dazhu123/p/12567414.html