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 <= N <= 50
- Answers will be in the range of 32-bit signed integer.
4键键盘。
假设你有一个特殊的键盘包含下面的按键:
Key 1: (A):在屏幕上打印一个 'A'。
Key 2: (Ctrl-A):选中整个屏幕。
Key 3: (Ctrl-C):复制选中区域到缓冲区。
Key 4: (Ctrl-V):将缓冲区内容输出到上次输入的结束位置,并显示在屏幕上。
现在,你只可以按键 N 次(使用上述四种按键),请问屏幕上最多可以显示几个 'A'呢?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4-keys-keyboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路是动态规划。这道题有点像爬楼梯那一类的动态规划。这里我们还是创建一个DP数组,dp[i] 的定义是到第 i 次按键之后,最多可以显示的 A 的个数。
首先如果只是一直按 A 键的话,dp[i] = dp[i - 1] + 1,或者这里也可以写成dp[i] = i,意思是走到第几步了,就可以显示几个 A
但是如果想优化的话,为了最大化收益,对于最后一步操作,只可能是按 A 键,或者是按Ctrl-V。同时如果是按Ctrl-V想最大化收益,需要有一个前提,就是已经Ctrl-A + Ctrl-C过了,所以这里我们需要的第二个 for 循环则是在处理这个部分。j 从 3 开始是因为第 0 步什么都没做,第 1 步是留给按 A 键,第 2 步留给 Ctrl-A。从第 3 步开始我们才可以Ctrl-V,或者说这个时候开始粘贴才有意义。j < i - 2 是因为假设第 j 步是 Ctrl-A 的话, 需要再预留起码两步,一步给 Ctrl-C,一步给 Ctrl-V。
时间O(n^2)
空间O(n)
Java实现
1 class Solution { 2 public int maxA(int n) { 3 int[] dp = new int[n + 1]; 4 for (int i = 1; i <= n; i++) { 5 // dp[i] = dp[i - 1] + 1; 6 dp[i] = i; 7 for (int j = 3; j < i - 2; j++) { 8 dp[i] = Math.max(dp[i], dp[j] * (i - (j + 1))); 9 } 10 } 11 return dp[n]; 12 } 13 }