1565 · 飞行棋 I

链接:LintCode 炼码

题解:

 坐标型动态规划:

class Solution {
public:
    /**
     * @param length: the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
    int modernLudo(int length, vector<vector<int>> &connections) {
        // Write your code here
        std::unordered_map<int, std::unordered_set<int>> graph;
        // 构建相关联的图
        for (auto& conn : connections) {
            graph[conn[0]].insert(conn[1]);
        }
        // 到达下表长度距离位置,最小的步数
        std::vector<int> dp(length+1, INT_MAX);
        // 初始化
        dp[0] = 0;
        dp[1] = 0; 
        for (int i = 2; i <= length; ++i) {
            // 1,2,3,4,5,6,7
            // 计算下当前i,可以由前几个位置过来
            int begin = std::max(i-6, 1);
            for (int j = begin; j < i; ++j) {
                // 由前一个位置,增加一步就可以到达
                dp[i] = std::min(dp[i], dp[j] + 1);
            }
            // 当前i作为起始的位置,可以零步到达哪些位置
            for (auto to : graph[i]) {
                dp[to] = min(dp[to], dp[i]);
            }
        }
        // 最少步数到达length长度
        return dp[length];
    }
};
class Solution {
public:
    /**
     * @param length: the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
    int modernLudo(int length, vector<vector<int>> &connections) {
        // Write your code here
        std::unordered_map<int, std::unordered_set<int>> graph;
        for (auto& conn : connections) {
            graph[conn[1]].insert(conn[0]);
        }
        std::vector<int> dp(length+1, INT_MAX);
        dp[0] = 0;
        dp[1] = 0;
        for (int i = 2; i <= length; ++i) {
            // 1,2,3,4,5,6,7
            int begin = std::max(i-6, 1);
            for (int j = begin; j < i; ++j) {
                dp[i] = std::min(dp[i], dp[j] + 1);
            }
            for (auto to : graph[i]) {
                dp[i] = min(dp[to], dp[i]);
            }
        }
        return dp[length];
    }
};
class Solution {
public:
    /**
     * @param length: the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
    int modernLudo(int length, vector<vector<int>> &connections) {
        // Write your code here
        if (length <= 0) {
            return 0;
        }
        std::unordered_map<int, std::unordered_set<int>> graph;
        for (auto& conn : connections) {
            graph[conn[0]].insert(conn[1]);
            graph[conn[1]].insert(conn[0]);
        }
        std::vector<int> dp(length, INT_MAX);
        dp[0] = 0;
        for (int i = 1; i < length; ++i) {
            int begin = std::max(i - 6, 0);
            for (int j = begin; j < i; ++j) {
                dp[i] = min(dp[i], dp[j] + 1);
            }
            cout << i << " " << dp[i] << endl;
            for (auto neigh : graph[i+1]) {
                dp[i] = min(dp[i], dp[neigh-1]);
            }
        }
        return dp[length-1];
    }
};

 

class Solution {
public:
    /**
     * @param length: the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
class Node {
public:
    Node(int n, int dist):distance(dist), node(n) {

    }
    int distance;
    int node;
public:
    bool operator < (const Node& n) const {
        return distance > n.distance ? true : false;
    }
};
    int modernLudo(int length, vector<vector<int>> &connections) {
        // Write your code here
        if (length <= 1) {
            return 0;
        }
        std::unordered_map<int, std::unordered_set<int>> graph;
        // 构建图
        for (auto& conn : connections) {
            graph[conn[0]].insert(conn[1]);
        }
        std::priority_queue<Node> que;
        que.push(Node(1, 0));
        //std::unordered_map<int, int> distance;
        // 初始化距离
        std::vector<int> distance(length+1, INT_MAX);
        // 初始化起始点
        distance[1] = 0;
        while (!que.empty()) {
            auto f = que.top();
            int dist = f.distance;
            int node = f.node;
            que.pop();
            // 判断邻居是否可以更新最短距离
            for (auto neigh : graph[node]) {
                if (distance[neigh] > dist) {
                    distance[neigh] = dist;
                    que.push(Node(neigh, dist));
                }
            }
            int limit = std::min(node+7, length+1);
            // 判断需要跳跃的节点,是否可以更新最短距离
            for (int i = node+1; i < limit; ++i) {
                if (distance[i] > dist + 1) {
                    distance[i] = dist + 1;
                    que.push(Node(i, dist+1));
                }
            }
        }
        return distance[length];
    }
};

class Solution {
public:
    /**
     * @param length: the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
    int modernLudo(int length, vector<vector<int>> &connections) {
        // Write your code here
        if (length <= 1) {
            return 0;
        }
        // 构建图
        std::unordered_map<int, std::unordered_set<int>> graph;
        for (auto& conn : connections) {
            graph[conn[0]].insert(conn[1]);
        }
        std::deque<int> que;
        // 入队初始化节点
        que.push_back(1);
        // 到达目标位置的最少步数
        std::unordered_map<int, int> distance;
        // 初始化起始节点
        distance[1] = 0;
        while (!que.empty()) {
            // 将相邻的节点,变为当前同一层进行遍历
            // 注意是取得que.size(),是把当前层所有相关联的节点,都放入到que中
            for (int i = 0; i < que.size(); ++i) {
                int node = que[i];
                for (auto direct_node : graph[node]) {
                    // 如果没有求得过最短距离
                    if (distance.find(direct_node) != distance.end()) {
                        continue;
                    } 
                    que.push_back(direct_node);
                    // 更新最短距离
                    distance[direct_node] = distance[node];
                }
            }
            // 获得下一层节点
            std::deque<int> next_que;
            int size = que.size();
            for (int i = 0; i < size; ++i) {
                auto node = que[i];
                // 求得当前节点为起始点,跳跃一次,可以到达的位置
                int limit = std::min(node+7, length+1);
                for (int neigh = node+1; neigh < limit; ++neigh) {
                    // 如果求得过最短距离
                    if (distance.find(neigh) != distance.end()) {
                        continue;
                    }
                    // 记录最短路径
                    next_que.push_back(neigh);
                    distance[neigh] = distance[node]+1;
                }
            }
            que = next_que;
        }
        return distance[length];
    }
};

class Solution {
public:
    /**
     * @param length: the length of board
     * @param connections: the connections of the positions
     * @return: the minimum steps to reach the end
     */
    int modernLudo(int length, vector<vector<int>> &connections) {
        // Write your code here
        if (length <= 1) {
            return 0;
        }
        // 构建图
        std::unordered_map<int, std::unordered_set<int>> graph;
        for (auto& conn : connections) {
            graph[conn[0]].insert(conn[1]);
        }
        // 初始化起始节点
        std::deque<int> que;
        que.push_back(1);
        std::unordered_map<int, int> distance;
        // 初始化起点距离
        distance[1] = 0;
        while (!que.empty()) {
            auto f = que.front();
            que.pop_front();
            int limit = std::min(f+7, length+1);
            // 从f为起点位置,可以达到最远位置是limit-1
            for (int next_node = f+1; next_node < limit; ++next_node) {
                // 如果节点已经计算过最短距离了,因为bfs是层级遍历,之前遍历过,肯定是最短距离
                if (distance.find(next_node) != distance.end()) {
                    continue;
                }
                // 更新下一个节点的最短距离
                distance[next_node] = distance[f] + 1;
                que.push_back(next_node);
                // 将周围相邻,可以直接跳跃的节点,更新distance
                get_neighboard_into_que(next_node, distance, graph, que);
                /*for (auto neigh : get_neighboard(next_node, distance, graph)) {
                    distance[neigh] = distance[f]+1;
                    que.push_back(neigh);
                }*/
            }
        }
        return distance[length];
    }
private:
    void get_neighboard_into_que(int node, std::unordered_map<int, int>& distance,
         std::unordered_map<int, std::unordered_set<int>>& graph, std::deque<int>& master_que) {
        std::deque<int> que;
        // 以node为起始节点,遍历所有相邻节点
        que.push_back(node);
        while (!que.empty()) {
            auto f = que.front();
            que.pop_front();
            // 邻居节点
            for (auto neigh : graph[f]) {
                // 访问过则不在访问
                if (distance.find(neigh) != distance.end()) {
                    continue;
                }
                // 更新邻居节点,以distance[node]赋值
                distance[neigh] = distance[node];
                // 继续遍历相邻节点
                que.push_back(neigh);
                // 更新主队列
                master_que.push_back(neigh);
            }
        }
    }
    std::vector<int> get_neighboard(int node, std::unordered_map<int, int>& distance,
         std::unordered_map<int, std::unordered_set<int>>& graph) {
        std::deque<int> que;
        que.push_back(node);
        std::vector<int> result;
        result.push_back(node);
        while (!que.empty()) {
            auto f = que.front();
            que.pop_front();
            for (auto neigh : graph[f]) {
                if (distance.find(neigh) != distance.end()) {
                    continue;
                }
                //distance[neigh] = distance[node];
                result.push_back(neigh);
                que.push_back(neigh);
            }
        }
        return result;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值