# Leetcode:No.651 4 Keys Keyboard

Imagine you have a special keyboard with the following keys:
Key 1: (A): Prints 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.

n=1,r=1
n=2,r=2
n=3,r=3

n=4，r=4

n=6,r=6

n=7的时候，又是一个需要思考的地方。按前面说的，6个A可以通过平A得到，也可以3个A再acv，acv的方法肯定更优，因为给后面留下了继续v的可能。

DP就不同了，只要知道关系式就行。

``````for j in xrange(3, i - 2):
dp[i] = max(dp[i], dp[i-j]*(j-1))
``````

``````# Time:  O(n^2)
# Space: O(n)
class Solution(object):
def maxA(self, n):
dp = [_ for _ in xrange(n + 1)]
for i in xrange(7, n + 1):
for j in xrange(3, i - 2):
dp[i] = max(dp[i], dp[i - j] * (j - 1))
return dp[-1]
``````

x0 + x1 + ... + xk = N - k
k >= 0
x0 >= 1
x1, ..., xk >= 2

4 * (k + 1) - delta = N - k, where 0 <= delta <= 4
k = (N + delta - 4) / 5 = N / 5

x=2因子为1，x=3因子为1.26，x=4因子为1.316，x=5因子为1.320，x=6因子为1.308.

``````# Time:  O(1)
# Space: O(1)
def maxA(self, N):
"""
:type N: int
:rtype: int
"""
if N < 7: return N
if N == 10: return 20  # the following rule doesn't hold when N = 10

n = N // 5 + 1  # n3 + n4 increases one every 5 keys
# (1) n     =     n3 +     n4
# (2) N + 1 = 4 * n3 + 5 * n4
#     5 x (1) - (2) => 5*n - N - 1 = n3
n3 = 5 * n - N - 1
n4 = n - n3
return 3 ** n3 * 4 ** n4
``````

n就是上面的k+1，理想情况下由x3的因子n3和x4的因子n4组成。

10 is special here because it's the only > 6 number where there is no enough factors to share cuts from decrement of the number of 3's which means a 5 has to be introduced.

``````# Time:  O(n)
# Space: O(1)
class Solution2(object):
def maxA(self, N):
"""
:type N: int
:rtype: int
"""
if N < 7: return N
dp = range(N + 1)
for i in xrange(7, N + 1):
dp[i % 6] = max(dp[(i - 4) % 6] * 3, dp[(i - 5) % 6] * 4)
return dp[N % 6]
``````