链接: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;
}
};