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 4 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]);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM