650. 只有两个键的键盘(中等)
-
思路
- 不同于以往通过加减实现的动态规划,这里需要乘除法计算位置。因为粘贴操作是倍数增加,使一个一维数组 dp,其中位置 i 表示延展到长度 i 的最少操作次数。
- 对于每个位置 j ,如果 j 可以被 i 整除,那么长度 i 就可以由长度 j 得到,其操作次数等价于把一个长度为 1 的 A 延展到长度为 i/j ,因此递推公式为:
dp[i] = dp[j] + dp[i/j];
。比如 i = 10 ,可以在 i=5 的时候,选择复制全部字符并粘贴,就扩展为 10 个 A。
-
代码
class Solution { public:int minSteps(int n) {vector<int> dp(n+1, 0);for(int i=2; i<=n; ++i){dp[i] = i;for(int j=2; j*j<=i; ++j){if(i % j == 0){dp[i] = dp[j] + dp[i/j]; break;}}}return dp[n];} };
-
收获
- 理解起来有点难,自己跟着代码算一下比较好理解。
- 我自己模拟的时候,计算错了,忘记复制全部字符,而我每次复制的字符都是之前复制的两倍(即 2 - 4 - 8 - …)。