【Lintcode】1565. Modern Ludo I

题目地址:

https://www.lintcode.com/problem/modern-ludo-i/description

给定一个长度为ll的一维棋盘,每个位置编号为1l1\sim l,再给定一个数组,表示棋盘的某两个位置有连接,对于每个连接,只能从第一个位置到第二个位置,不能反向,题目保证连接的两个位置中第一个位置编号比第二个小,并且保证第一个位置的编号一定不是11。现在从11这个位置开始出发,每次可以通过掷骰子走161\sim 6步,或者通过连接直接移动到另一个位置。问至少掷多少次骰子可以到达ll编号的位置。

可以用动态规划。首先如果长度l7l\le 7,那么显然只需一次。接下来开始从22遍历到ll,每次遍历的时候更新后面66位需要的次数,并且如果有连接,更新到达的位置的次数。代码如下:

import java.util.*;

public class Solution {
    /**
     * @param length:      the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
    public int modernLudo(int length, int[][] connections) {
        // Write your code here
        if (length <= 7) {
            return 1;
        }
        
        Map<Integer, Set<Integer>> map = new HashMap<>();
        for (int[] connection : connections) {
            map.putIfAbsent(connection[0], new HashSet<>());
            map.get(connection[0]).add(connection[1]);
        }
        
        int[] dp = new int[length + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        
        for (int i = 2; i <= 7; i++) {
            dp[i] = 1;
        }
        
        for (int i = 2; i <= length; i++) {
            if (map.containsKey(i)) {
                for (int target : map.get(i)) {
                    dp[target] = Math.min(dp[target], dp[i]);
                }
            }
            for (int j = 1; j <= 6; j++) {
                if (i + j <= length) {
                    dp[i + j] = Math.min(dp[i + j], dp[i] + 1);
                }
            }
        }
        
        return dp[length];
    }
}

时空复杂度O(n)O(n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章