[LeetCode] 4 Keys Keyboard 四鍵的鍵盤


 

Imagine you have a special keyboard with the following keys:

Key 1: (A): Print one 'A' on screen.

Key 2: (Ctrl-A): Select the whole screen.

Key 3: (Ctrl-C): Copy selection to buffer.

Key 4: (Ctrl-V): Print buffer on screen appending it after what has already been printed.

Now, you can only press the keyboard for N times (with the above four keys), find out the maximum numbers of 'A' you can print on screen.

Example 1:

Input: N = 3
Output: 3
Explanation: 
We can at most get 3 A's on screen by pressing following key sequence:
A, A, A

 

Example 2:

Input: N = 7
Output: 9
Explanation: 
We can at most get 9 A's on screen by pressing following key sequence:
A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V

 

Note:

  1. 1 <= N <= 50
  2. Answers will be in the range of 32-bit signed integer.

 

這道題給了我們四個操作,分別是打印A,全選,復制,粘貼。每個操作都算一個步驟,給了我們一個數字N,問我們N個操作最多能輸出多個A。我們可以分析題目中的例子可以發現,N步最少都能打印N個A出來,因為我們可以每步都是打印A。那么能超過N的情況肯定就是使用了復制粘貼,這里由於全選和復制要占用兩步,所以能增加A的個數的操作其實只有N-2步,那么我們如何確定打印幾個A,剩下都是粘貼呢,其實是個trade off,A打印的太多或太少,都不會得到最大結果,所以打印A和粘貼的次數要接近,最簡單的方法就是遍歷所有的情況然后取最大值,打印A的次數在[1, N-3]之間,粘貼的次數為N-2-i,加上打印出的部分,就是N-1-i了,參見代碼如下:

 

解法一:

class Solution {
public:
    int maxA(int N) {
        int res = N;
        for (int i = 1; i < N - 2; ++i) {
            res = max(res, maxA(i) * (N - 1 - i));
        }
        return res;
    }
};

 

這道題也可以用DP來做,我們用一個一維數組dp,其中dp[i]表示步驟總數為i時,能打印出的最多A的個數,初始化為N+1個,然后我們來想遞推公式怎么求。對於dp[i]來說,求法其實跟上面的方法一樣,還是要遍歷所有打印A的個數,然后乘以粘貼的次數加1,用來更新dp[i],參見代碼如下:

 

解法二:

class Solution {
public:
    int maxA(int N) {
        vector<int> dp(N + 1, 0);
        for (int i = 0; i <= N; ++i) {
            dp[i] = i;
            for (int j = 1; j < i - 2; ++j) {
                dp[i] = max(dp[i], dp[j] * (i - j - 1));
            }
        }
        return dp[N];
    }
};

 

這道題還有個O(1)時間復雜度的解法,好像利用了數學知識,不過博主貌似沒太理解,參見這個帖子,哪位大神給博主講解一下?

 

類似題目:

2 Keys Keyboard

 

參考資料:

https://discuss.leetcode.com/topic/97764/o-1-time-o-1-space-c-solution-possibly-shortest-and-fastest

https://discuss.leetcode.com/topic/97628/java-4-lines-recursion-with-step-by-step-explanation-to-derive-dp

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM