题目描述-四键键盘
解题思路
状态转移:
- 第一个状态是剩余的按键次数, 用n 表示;
- 第二个状态是当前屏幕上字符 A 的数量, 用a_num 表示;
- 第三个状态是剪切板中字符 A 的数量, 用copy 表示。
base case: 当剩余次数 n 为 0 时, a_num就是我们想要的答案。
dp(n - 1, a_num + 1, copy), # A
解释: 按下 A 键, 屏幕上加⼀个字符
同时消耗 1 个操作数
dp(n - 1, a_num + copy, copy), # C-V
解释: 按下 C-V 粘贴, 剪切板中的字符加⼊屏幕
同时消耗 1 个操作数
dp(n - 2, a_num, a_num) # C-A C-C
解释: 全选和复制必然是联合使⽤的,
剪切板中 A 的数量变为屏幕上 A 的数量
同时消耗 2 个操作数
题解:
public static int maxA(int N){
int[] dp = new int[N + 1];
dp[0] = 0;
for (int i = 1;i <= N;i++){
//按A键
dp[i] = dp[i - 1] + 1;
for (int j = 2;j < i;j++){
//全选 & 复制dp[j - 2],连续粘贴i - j次
//屏幕上共dp[j-2] * (i - j + 1)个A
dp[i] = Math.max(dp[i],dp[j -2]*(i - j + 1));
}
}
//N次按键之后最多有几个A?
return dp[N];
}
题目描述-两键键盘
最初在一个记事本上只有一个字符 ‘A’。你每次可以对这个记事本进行两种操作:
Copy All (复制全部) : 你可以复制这个记事本中的所有字符(部分的复制是不允许的)。
Paste (粘贴) : 你可以粘贴你上一次复制的字符。
给定一个数字 n 。你需要使用最少的操作次数,在记事本中打印出恰好 n 个 ‘A’。输出能够打印出 n 个 ‘A’ 的最少操作次数。
示例 1:
输入: 3
输出: 3
解释:
最初, 我们只有一个字符 ‘A’。
第 1 步, 我们使用 Copy All 操作。
第 2 步, 我们使用 Paste 操作来获得 ‘AA’。
第 3 步, 我们使用 Paste 操作来获得 ‘AAA’。
解题思路
public static int minSteps(int n){
int[] dp = new int[n+1];
int h=(int) Math.sqrt(n);
for (int i=2;i <= n;i++){
dp[i] = i;
for (int j = 2; j <= h; j++) {
if (i % j == 0){
dp[i] = dp[j] + dp[i/j];
break;
}
}
}
return dp[n];
}