您的位置:首页 > 其它

leetcode 651. 4 Keys Keyboard

2017-08-02 13:00 489 查看
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 <= N <= 50
Answers will be in the range of 32-bit signed integer.
使用DP。

首先把 DP[ i ] 初始化为 i,代表的情形是不使用复制粘贴操作。然后将 j 从3开始一直到 i-1,从3开始是为了确保至少有一个复制粘贴的操作。接着循环:"以dp[1] 中的所有字符为基准之后全是粘贴操作" 一直到 "以dp[i-3]中的所有字符为基准之后全是粘贴操作"。

比如:

A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V

这里 
n = 7
 ,我们使用了 
3
 (j=4,i-j=7-4)步来获得 
AAA


接着我们使用 
4
 步: Ctrl A, Ctrl C, Ctrl V, Ctrl V, 来获得
j
- 1 = 4 - 1 = 3
 份 
AAA 的复制。

我们要么一点不使用copy操作,就是我们初始化 DP[ i ] 为 i 的情形。要么使用copy操作,这样我们要留3步给 Ctrl A, Ctrl C, Ctrl V ,所以 j 至少是 
3
.

得到公式 dp[ i ] = max ( dp[ i ] , dp[ i - j ] * ( j - 1 ) )      {  j in [ 3, i )  }
public int maxA(int N) {
int[] dp = new int[N+1];
for(int i=1;i<=N;i++){
dp[i] = i;
for(int j=3;j<i;j++){
dp[i] = Math.max(dp[i], dp[i-j] * (j-1));
}
}
return dp
;
}


还有一种类似的想法。

使用 
i
 步来获得 
maxA(i)
 ,然后用剩下的 
n
- i
 步来获得 
n - i - 1
 个 
maxA(i)
的复制。

比如:

A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V

这里 
n = 7
 ,我们使用 
i
= 3
 步来获得 
AAA


接着我们使用剩下的 
n - i = 4
 步: Ctrl A, Ctrl C, Ctrl V, Ctrl V, 来获得 
n
- i - 1 = 3
 个 
AAA
的复制。

如果我们不使用copy,那么答案就是 
n
, 或者我们使用copy,那么需要有3步来预留给 Ctrl A, Ctrl C, Ctrl V ,所以 
i
 最多为 
n
- 3。

public int maxA(int n) {
int max = n;
for (int i = 1; i <= n - 3; i++)
max = Math.max(max, maxA(i) * (n - i - 1));
return max;
}
DP解法:
public int maxA(int n) {
int[] dp = new int[n + 1];
for (int i = 0; i <= n; i++) {
dp[i] = i;
for (int j = 1; j <= i - 3; j++)
dp[i] = Math.max(dp[i], dp[j] * (i - j - 1));
}
return dp
;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: