1. 程式人生 > >514. 自由之路

514. 自由之路

視訊遊戲“輻射4”中,任務“通向自由”要求玩家到達名為“Freedom Trail Ring”的金屬錶盤,並使用錶盤拼寫特定關鍵詞才能開門。

給定一個字串 ring,表示刻在外環上的編碼;給定另一個字串 key,表示需要拼寫的關鍵詞。您需要算出能夠拼寫關鍵詞中所有字元的最少步數。

最初,ring 的第一個字元與12:00方向對齊。您需要順時針或逆時針旋轉 ring 以使 key 的一個字元在 12:00 方向對齊,然後按下中心按鈕,以此逐個拼寫完 key 中的所有字元。

旋轉 ring 拼出 key 字元 key[i] 

的階段中:

  1. 您可以將 ring 順時針或逆時針旋轉一個位置,計為1步。旋轉的最終目的是將字串 ring 的一個字元與 12:00 方向對齊,並且這個字元必須等於字元 key[i] 。
  2. 如果字元 key[i] 已經對齊到12:00方向,您需要按下中心按鈕進行拼寫,這也將算作 1 步。按完之後,您可以開始拼寫 key 的下一個字元(下一階段), 直至完成所有拼寫。

示例:

 

 

輸入: ring = "godding", key = "gd"
輸出:
4 解釋: 對於 key 的第一個字元 'g',已經在正確的位置, 我們只需要1步來拼寫這個字元。 對於 key 的第二個字元 'd',我們需要逆時針旋轉 ring "godding" 2步使它變成 "ddinggo"。 當然, 我們還需要1步進行拼寫。 因此最終的輸出是 4。

提示:

  1. ring 和 key 的字串長度取值範圍均為 1 至 100;
  2. 兩個字串中都只有小寫字元,並且均可能存在重複字元;
  3. 字串 key 一定可以由字串 ring 旋轉拼出。

class Solution {
public:
    int findRotateSteps(string ring, string key) {
        int n = ring.size(), m = key.size();
        vector<vector<int>> dp(m + 1, vector<int>(n));
        for (int i = m - 1; i >= 0; --i) {
            for (int j = 0; j < n; ++j) {
                dp[i][j] = INT_MAX;
                for (int k = 0; k < n; ++k) {
                    if (ring[k] == key[i]) {
                        int diff = abs(j - k);
                        int step = min(diff, n - diff);
                        dp[i][j] = min(dp[i][j], step + dp[i + 1][k]);
                    }
                }
            }
        }
        return dp[0][0] + m;      
    }
};