日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

818. Race Car

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 818. Race Car 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1 題目理解
  • 2 BFS
  • 3 dp
    • 3.1 基本情況
    • 3.2 遞歸方程分析
      • 3.2.1 先超過target再調頭
      • 3.2.2 不超過target
  • 4 說明

1 題目理解

先講規則。一輛小汽車停在位置0,并且方向朝向右側,并且速度為1。小汽車每次可以選擇加速A,那加速一次,新的位置=原來位置+速度,并且新的速度=速度*2。小汽車也可以選擇掉頭。掉頭一次的話,新的位置=原來的位置,并且新的速度=如果原來速度>0,那就是-1,否則的話是1。
輸入:int target。
輸出:小汽車到達位置target最少需要幾次操作。
例子:
Example 1:
Input:
target = 3
Output: 2
Explanation:
最短的操作順序 是: “AA”.
汽車位置變化為: 0->1->3.

Example 2:
Input:
target = 6
Output: 5
Explanation:
最短的操作順序 是 “AAARA”.
汽車位置變化為 0->1->3->7->7->6.

題目分析思路來源于花花醬。

2 BFS

因為在每個位置上,有兩種操作。在每次操作后速度、位置會發生變化。一直變,直到走到終點。所以可以按照BFS求解。遇到的第一個位置為target,就是最短的操作。
這里有幾個關鍵點。
關鍵點1:如果相同的位置和速度已經加入過隊列,那就不需要再次計算。
關鍵點2:如果在位置0,小汽車朝向右側一定比朝向左側用的操作最少。這個可以用反證法證明。
關鍵點3:小汽車向右走,可以超過target,但 不能超過2*target。否則操作數會更多。
當然這個方法是不能AC的。

class Solution {public int racecar(int target) {Queue<int[]> queue = new LinkedList<int[]>();List<String> filter = new ArrayList<String>();queue.offer(new int[]{0,1});//pos speedfilter.add(0+"_"+1);filter.add("0_-1");int step = 0;while(!queue.isEmpty()){int size = queue.size();for(int i=0;i<size;i++){int[] values = queue.poll();int pos = values[0];int speed = values[1];//Aint newpos = pos + speed;if(newpos == target){return step + 1;}if(pos < 2*target){queue.offer(new int[]{newpos,speed*2});filter.add(newpos+"_"+(speed*2));}//Rif(speed >=0 ){speed = -1;}else{speed = 1;}String key = pos+"_"+speed;if(!filter.contains(key)){queue.offer(new int[]{pos,speed});filter.add(key);}}step++;}return -1;} }

通過這個方法我們知道在同一位置可能有兩種狀態:速度向右、速度向左。這提示我們在做動態規劃的時候可能需要維護二維數組。

3 dp

如果target=7,我們發現

操作位置速度
起始01
第1次A12
第2次A34
第3次A78

3.1 基本情況

如果target=2n?1target = 2^n-1target=2n?1,那么到達target的最少操作數是n。是dp中的基本情況。

3.2 遞歸方程分析

如果不是,則可能要考慮兩種情況。第一種情況是先走過5達到7,因為7的最少操作數可以直接求解,是基本情況。然后再調頭,需要走2個位置達到5。如果我們提前計算好了走距離2的最少操作數,那就可以求解了。第二種情況是可能走到j=1,2,3,4,然后再走剩下的距離。操作數之和就是達到5的操作數。兩種情況求最小值就是答案。下面分別討論。

令dp[i][0]表示從0達到位置i并且速度朝右的最小操作數。dp[i][1]表示從0達到位置i并且速度朝左的最小操作數。

3.2.1 先超過target再調頭

例如上面到達7,再返回達到5的時候可能速度方向朝左,也可能朝右。
dp[7][0]=3,dp[7][1]=4。
達到7調頭,這時候操作數是4。
繼續走2個距離,這時候的操作數是dp[2][0],這個時候的方向是朝左的。也就是說dp[5][1]= 4 + dp[2][0]。為什么是dp[2][0]而不是dp[2][1]呢?dp[2][0]表示從0到達2,并且方向向右,又因為起始位置速度的方向也向右,所以可以認為走過2個位置,并且方向和起始方向相同的最少操作數是dp[2][0]。當到達7以后調頭,方向向左了,走過2個距離并且速度方向一致,那操作數就是dp[2][0]。
當然dp[5][1],也可能是通過dp[2][1]獲得,這個時候需要再加一個轉向操作,所以dp[5][1]=4+dp[2][1]+1。兩者取最小值。dp[5][1] = 4 + min(dp[2][0],dp[2][1]+1)。
同理,可以推出dpp[5][0] = 4 + min(dp[2][1],dp[2][0]+1)。

推出一般情況就是:
l=2n?1?targetl=2^n-1-targetl=2n?1?target
dp[target][0]=n+1+min(dp[l][1],dp[l][0]+1)dp[target][0] = n +1 + min(dp[l][1],dp[l][0]+1)dp[target][0]=n+1+min(dp[l][1],dp[l][0]+1)
dp[target][1]=n+1+min(dp[l][0],dp[l][1]+1)dp[target][1] = n +1 + min(dp[l][0],dp[l][1]+1)dp[target][1]=n+1+min(dp[l][0],dp[l][1]+1)

3.2.2 不超過target

再參考上圖target=5,如果不超過5。
那我們可以先走距離1,到達1以后再走距離4。到達5。
我們也可以先走距離2,到達2以后再走距離3。到達5。

我們也可以先走距離4,到達4以后再走距離1。到達5。

我們先分析先走距離1,到達1以后再走距離4。到達5的情況。達到1,如果方向向右,則需要先 調頭,再調頭,然后走距離4。那么dp[5][0] = dp[1][0]+2 + dp[4][0]。達到1,如果方向向左,則需要先調頭,然后走距離4。那么dp[5][0] = dp[1][1]+1 + dp[4][0]。最終dp[5][0] = min(dp[1][1]+1,dp[1][0]+2) + dp[4][0]。
同理:dp[5][1] = min(dp[1][1]+1,dp[1][0]+2) + dp[4][1]。

最終代碼

class Solution {public int racecar(int target) {int[][] dp = new int[target+1][2];dp[0][0] = 0;dp[0][1] = 1;for(int i=1;i<=target;i++){int n = (int)Math.ceil(Math.log(i+1)/Math.log(2));if((1<<n) == i+1){dp[i][0] = n;dp[i][1] = n+1;}else{int left = ((1<<n)-1 - i);dp[i][0] = n+1+Math.min(dp[left][1],dp[left][0]+1);dp[i][1] = n+1+Math.min(dp[left][0],dp[left][1]+1);for(int j = 1;j<i;j++){int min = Math.min(dp[j][0]+2,dp[j][1]+1);dp[i][0] = Math.min(dp[i][0], min+dp[i-j][0]);dp[i][1] = Math.min(dp[i][1], min+dp[i-j][1]);}}}return Math.min(dp[target][0],dp[target][1]);} }

4 說明

看到題目還是應該拿著具體數值分析一下。在某一特定情況下是怎么到達目的地的。

總結

以上是生活随笔為你收集整理的818. Race Car的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。