2018-10-26 21:06:54

问题描述:

问题求解:

方法一、BFS

首先将使用BFS进行解空间的遍历,也就是将本问题转化成了搜索问题,但是有两个地方需要注意:

1、状态保存的问题,每个位置的状态由其位置信息和速度信息构成,但是如果将所有的位置出现过的速度进行保存会MLE,这里进行了一步简化,只保存当前位置速度绝对值为1的状态,定义这些状态不再后续的求解中被重复扩展;

2、Pruning,必须剪枝,如果不剪枝,则会TLE,这里采取的剪枝策略是将所有扩展到的距离target长度大于target的pos放弃。

3、状态保存采用了字符串拼接,这里可以进行进一步的优化。

    public int racecar(int target) {
int step = 0;
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{0, 1});
Set<String> set = new HashSet();
set.add("0_1");
set.add("0_-1");
while (!q.isEmpty()) {
step++;
int size = q.size();
for (int i = 0; i < size; i++) {
int[] cur = q.poll();
int pos = cur[0] + cur[1];
int speed = cur[1] * 2;
if (pos == target) return step;
if (Math.abs(pos - target) < target)
q.add(new int[]{pos, speed});
pos = cur[0];
speed = cur[1] > 0 ? -1 : 1;
String state = String.valueOf(pos) + "_" + String.valueOf(speed);
if (set.contains(state)) continue;
set.add(state);
q.add(new int[]{pos, speed});
}
}
return -1;
}

方法二、BFS + Integer状态

使用String来保存状态,在每次用Hash查询的时候开销非常大,这里可以使用Integer来进行优化。时间是原来是1/4,应该来说速度上提升还是很多的。

    public int racecar(int target) {
int step = 0;
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{0, 1});
Set<Integer> set = new HashSet();
set.add(0 << 2 | 1);
set.add(0 << 2 | 2);
while (!q.isEmpty()) {
step++;
int size = q.size();
for (int i = 0; i < size; i++) {
int[] cur = q.poll();
int pos = cur[0] + cur[1];
int speed = cur[1] * 2;
if (pos == target) return step;
if (Math.abs(pos - target) < target)
q.add(new int[]{pos, speed});
pos = cur[0];
speed = cur[1] > 0 ? -1 : 1;
Integer state = pos << 2 | ((speed == 1) ? 1 : 2);
if (set.contains(state)) continue;
set.add(state);
q.add(new int[]{pos, speed});
}
}
return -1;
}

方法三、DP

本题使用DP是最优解。

dp[i] : 在位置i的最短步数

有一个特殊情况,就是当前的pos正好等于2 ^ n - 1,此时所需步数可以直接运算出来,即d[i] = n    if i == 2 ^ n - 1

如果当前的pos不是最佳情况,那么就有两种策略,一是先经过pos,在往回倒,二是在到达之前进行倒车再前进。

算法的时间复杂度分析:总的状态数为t,每个状态求解的均摊时间在logt,所以时间复杂度为O(nlogn)。使用Java运行时间为3ms,beat 100%。

    public int racecar(int target) {
int[] dp = new int[target + 1];
return helper(target, dp);
} private int helper(int target, int[] dp) {
if (dp[target] != 0) return dp[target];
int n = (int) Math.ceil(Math.log(target + 1) / Math.log(2));
if (1 << n == target + 1) return dp[target] = n;
dp[target] = n + 1 + helper((1 << n) - 1 - target, dp);
for (int m = 0; m < n - 1; m++) {
int pos = (1 << (n - 1)) - (1 << m);
dp[target] = Math.min(dp[target], n + m + 1 + helper(target - pos, dp));
}
return dp[target];
}

动态规划-Race Car的更多相关文章

  1. 【DP专辑】ACM动态规划总结

    转载请注明出处,谢谢.   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 ...

  2. 【DP专辑】ACM动态规划总结(转)

    http://blog.csdn.net/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强, ...

  3. 集训第五周动态规划 H题 回文串统计

    Hrdv is interested in a string,especially the palindrome string.So he wants some palindrome string.A ...

  4. (转)dp动态规划分类详解

    dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间 ...

  5. HDU 1052 Tian Ji -- The Horse Racing【贪心在动态规划中的运用】

    算法分析: 这个问题很显然可以转化成一个二分图最佳匹配的问题.把田忌的马放左边,把齐王的马放右边.田忌的马A和齐王的B之间,如果田忌的马胜,则连一条权为200的边:如果平局,则连一条权为0的边:如果输 ...

  6. 增强学习(三)----- MDP的动态规划解法

    上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...

  7. 简单动态规划-LeetCode198

    题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...

  8. 动态规划 Dynamic Programming

    March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...

  9. 动态规划之最长公共子序列(LCS)

    转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...

随机推荐

  1. devexpress 之 ChartControl

    \}5#~mV#cr(/k1yIZ7.Lg

  2. 01:saltstack 基本使用

    1.1 准备实验环境: 安装系统 1)硬件配置如下 2) 先把光标放到”install CentOS 7”,按 Tab键编辑内核参数,添加 (net.ifnames=0 biosdevname=0) ...

  3. 监控mysql状态脚本

    监控mysql状态, 发现宕后, 自动重启, 每秒检查一次. check.sh #!/bin/bash while [ true ]; do /bin/sleep 1 sh mysql_status. ...

  4. 20145326蔡馨熤《网络对抗》——MSF基础应用

    20145326蔡馨熤<网络对抗>——MSF基础应用 实验后回答问题 用自己的话解释什么是exploit,payload,encode. exploit:起运输的作用,将数据传输到对方主机 ...

  5. JS实现页面字体繁简转换

    封装的JS代码 // 网页简繁体转换 // 本js用于客户在网站页面选择繁体中文或简体中文显示,默认是正常显示,即简繁体同时显示 // 在用户第一次访问网页时,会自动检测客户端语言进行操作并提示.此功 ...

  6. tomcat8.5之后版本,远程无法登录管理页面

    转载自http://jingyan.baidu.com/article/1612d500b56fa1e20e1eeed2.html 服务器采用的是linux系统. 安装tomcat在服务器上后,客户端 ...

  7. Eclipse之maven插件link方式安装

    maven是开发人员要具备的必不可少的技能之一.在使用eclipse进行开发时,我们需要安装maven插件,网上有很多教程,但是有些教程写的太过模糊.在此,我将自己的安装方法总结一下,尽量细致. 前提 ...

  8. 一个查表置换的CM

    说实话,今天被自己蠢哭了 因为看多了一个字符,以为是输入字符变形后的base64编码,也怪自己没大致看过base64汇编形式,把base64跟完了用py实现完算法才意思到是base64,这是题外话 本 ...

  9. js动画(速度)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta ht ...

  10. hihoCoder week227 Longest Subsequence

    题目链接 https://hihocoder.com/contest/hiho227/problem/1 题目详解 https://hihocoder.com/discuss/question/558 ...