The 4 Keys Keyboard problem asks: Imagine you have a special keyboard with only four keys:
n
(the total number of allowed key presses), return the maximum number of 'A's you can print on the screen using exactly n
key presses. You must decide the optimal sequence of these four operations to maximize the output.
Constraints:
n
≤ 50At first glance, it might seem optimal to just press 'A' repeatedly, but with the copy-paste operations, there might be a more efficient way to multiply the number of 'A's. The challenge is to figure out when to use the copy-paste sequence to maximize the output. We need to balance between simply typing 'A' and using the more powerful copy-paste operations.
A brute-force approach would be to try every possible sequence of operations, but this quickly becomes infeasible as n
grows. Instead, we look for patterns or subproblems we can solve efficiently, such as:
n
and use them to solve larger ones.
We'll use dynamic programming to solve this problem efficiently. The idea is to keep track of the maximum number of 'A's that can be produced with a given number of key presses.
dp[i]
represent the maximum number of 'A's that can be printed with i
key presses.
i
from 1 to n
:
dp[i] = dp[i-1] + 1
.j
).j
, perform Ctrl-A
, Ctrl-C
(2 steps), and then multiple Ctrl-V
(each paste is one step).j
(where j < i-2
), calculate:
i - j - 2
(since 2 steps for select and copy).
dp[j] * (number of pastes + 1)
(the original plus all pastes).
dp[i]
if this gives a higher value.
This approach ensures we always have the best possible number of 'A's for each number of key presses, using previously computed results for efficiency. We use an array for dp
because it allows constant-time access and updates.
Let's walk through an example with n = 7
:
dp[3] = 3
).dp[2] = 2
).n = 7
.
The DP array would look like this for n=7
:
[0, 1, 2, 3, 4, 5, 6, 9]
n
up to 50.
i
from 1 to n
, we check all j
from 1 to i - 3
(since we need at least 3 steps for select, copy, and one paste). So, it's O(n^2) time.
dp
array.
This is efficient for the given constraints.
The 4 Keys Keyboard problem is a classic dynamic programming challenge. The key insight is that the optimal strategy often involves building up a sequence of 'A's, then using select-copy-paste to multiply your progress. By using a DP array, we efficiently compute the best result for every number of key presses, always considering if a copy-paste sequence can beat simply typing 'A'. This approach is both elegant and efficient for the problem's constraints.
class Solution:
def maxA(self, n: int) -> int:
dp = [0] * (n + 1)
for i in range(1, n + 1):
# Press 'A'
dp[i] = dp[i - 1] + 1
# Try all possible copy-paste sequences
for j in range(1, i - 2):
# At step j: select all, copy, then paste (i - j - 2) times
dp[i] = max(dp[i], dp[j] * (i - j - 1))
return dp[n]
class Solution {
public:
int maxA(int n) {
vector<int> dp(n + 1, 0);
for (int i = 1; i <= n; ++i) {
dp[i] = dp[i - 1] + 1;
for (int j = 1; j < i - 2; ++j) {
dp[i] = max(dp[i], dp[j] * (i - j - 1));
}
}
return dp[n];
}
};
class Solution {
public int maxA(int n) {
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
dp[i] = dp[i - 1] + 1;
for (int j = 1; j < i - 2; j++) {
dp[i] = Math.max(dp[i], dp[j] * (i - j - 1));
}
}
return dp[n];
}
}
var maxA = function(n) {
let dp = new Array(n + 1).fill(0);
for (let i = 1; i <= n; i++) {
dp[i] = dp[i - 1] + 1;
for (let j = 1; j < i - 2; j++) {
dp[i] = Math.max(dp[i], dp[j] * (i - j - 1));
}
}
return dp[n];
};