最初在一个记事本上只有一个字符 'A'。你每次可以对这个记事本进行两种操作:

  Copy All (复制全部) : 你可以复制这个记事本中的所有字符(部分的复制是不允许的)。
  Paste (粘贴) : 你可以粘贴你上一次复制的字符。

给定一个数字 n 。你需要使用最少的操作次数,在记事本中打印出恰好 n 个 'A'。输出能够打印出 n 个 'A' 的最少操作次数。

示例 1:

输入: 3
输出: 3
解释:
最初, 我们只有一个字符 'A'。
第 1 步, 我们使用 Copy All 操作。
第 2 步, 我们使用 Paste 操作来获得 'AA'。
第 3 步, 我们使用 Paste 操作来获得 'AAA'。

说明:

n 的取值范围是 [1, 1000] 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/2-keys-keyboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

第一反应是二维DP

dp[i][j] 表示总共i个字母 粘贴板有j个字母 的最小步骤

class Solution {
public:
int minSteps(int n) {
// dp[i][j] 总共i个字母 粘贴板有j个字母 的最小步骤
int dp[n+1][n+1];
memset(dp, -1, sizeof dp);
dp[1][0] = 0;
int ans = -1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= i; j++) {
if (dp[i][j] != -1) {
if (dp[i][i] == -1 || dp[i][i] > dp[i][j] + 1) {
dp[i][i] = dp[i][j] + 1;
}
if (i + j <= n && (dp[i + j][j] == -1 || dp[i + j][j] > dp[i][j] + 1)) {
dp[i + j][j] = dp[i][j] + 1;
}
}
if (i == n && dp[i][j] != -1 && (ans == -1 || ans > dp[i][j])) {
ans = dp[i][j];
}
}
}
return ans;
}
};

不过运行速度有点慢……

对于任何一个数 n,都可以先凑到该数的一个因数 x ,然后 copy all 复制 n/x-1 次,枚举因数即可

如果 n 为质数,就只能使用 1 来复制 n-1 次

class Solution {
public:
int minSteps(int n) {
int dp[n+1] = {0};
for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int j = 1; j < i; j++) {
if (i % j == 0) {
dp[i] = min(dp[i], dp[j] + i / j);
}
}
}
return dp[n];
}
};

复杂度和上面一样,O(n^2) 不过可以优化一下

考虑到一个数x=p*q, p和q是两个质数,那么总共打印的次数就是先打印 p 个字母 然后复制 q 次,或者先打印 q 个字母,复制 p 次,结果都是一样的 p+q

在 p > 1 且 q > 1 的条件下 p*q >= p+q 永远成立,所以先打印因数个字母再复制的打印方法是最优的。

所以将n做质因数分解就可以了,比如 36=2*2*3*3 答案就是 dp[36]=dp[2]+dp[2]+dp[3]+dp[3],又知道所有的质数答案都是固定的(即该数本身),也就是说 36=2+2+3+3=10

class Solution {
public:
int minSteps(int n) {
int ans = 0;
for (int i = 2; i <= n; i++) {
while (n % i == 0) {
n /= i;
ans += i;
}
}
return ans;
}
};

LeetCode 650. 2 Keys Keyboard(只有两个键的键盘)(DP/质因数分解)的更多相关文章

  1. 【LeetCode】650. 2 Keys Keyboard 只有两个键的键盘(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 素数分解 日期 题目地址:https://le ...

  2. [LeetCode] 650. 2 Keys Keyboard 两键的键盘

    Initially on a notepad only one character 'A' is present. You can perform two operations on this not ...

  3. [leetcode] 650. 2 Keys Keyboard (Medium)

    解法一: 暴力DFS搜索,对每一步进行复制还是粘贴的状态进行遍历. 注意剪枝的地方: 1.当前A数量大于目标数量,停止搜索 2.当前剪贴板数字大于等于A数量时,只搜索下一步为粘贴的状态. Runtim ...

  4. LeetCode 650 - 2 Keys Keyboard

    LeetCode 第650题 Initially on a notepad only one character 'A' is present. You can perform two operati ...

  5. [LeetCode] 651. 4 Keys Keyboard 四键的键盘

    Imagine you have a special keyboard with the following keys: Key 1: (A): Print one 'A' on screen. Ke ...

  6. Java实现 LeetCode 650 只有两个键的键盘(递归 || 数学)

    650. 只有两个键的键盘 最初在一个记事本上只有一个字符 'A'.你每次可以对这个记事本进行两种操作: Copy All (复制全部) : 你可以复制这个记事本中的所有字符(部分的复制是不允许的). ...

  7. Leetcode 650.只有两个键的键盘

    只有两个键的键盘 最初在一个记事本上只有一个字符 'A'.你每次可以对这个记事本进行两种操作: Copy All (复制全部) : 你可以复制这个记事本中的所有字符(部分的复制是不允许的). Past ...

  8. 【LeetCode】650. 只有两个键的键盘

    只有两个键的键盘 最初在一个记事本上只有一个字符 'A'.你每次可以对这个记事本进行两种操作: 1.Copy All (复制全部) : 你可以复制这个记事本中的所有字符(部分的复制是不允许的). 2. ...

  9. LC 650. 2 Keys Keyboard

    Initially on a notepad only one character 'A' is present. You can perform two operations on this not ...

  10. [Swift]LeetCode650. 只有两个键的键盘 | 2 Keys Keyboard

    Initially on a notepad only one character 'A' is present. You can perform two operations on this not ...

随机推荐

  1. .NET 中高效 Excel 解决方案 MiniExcel

    前言 MiniExcel 是一个用于 .NET 平台的轻量级.高性能的库,专注于提供简单易用的 API 来处理 Excel 文件.以下是 MiniExcel 的特点总结: 轻量级与高效:MiniExc ...

  2. 深度解读GaussDB(for MySQL)与MySQL的COUNT查询并行优化策略

    本文分享自华为云社区<[华为云MySQL技术专栏]GaussDB(for MySQL)与MySQL的COUNT查询并行优化策略>,作者:GaussDB 数据库. 1.背景介绍 统计表的行数 ...

  3. linux的一些常用端口

    hdfs:9870 yarn:8088 sparkMaster的端口是:8080 worker的端口是:8081 历史服务器的默认端口是: 18080

  4. ceph 003 对osd操作 对存储池操作 存储池配额 存储池快照 pgp

    主机被加入集群时,会自动被分配角色以达到集群的默认状态.(mon,mgr之类) 想要超过默认状态可以进行设置 ceph容器与客户端 ceph集群的客户端 需要 ceph-common 软件包 ceph ...

  5. Jmeter函数助手10-regexFunction

    regexFunction函数用于对上一个请求进行正则表达式提取处理,类似正则表达式. 用于从前一个请求搜索结果的正则表达式:填入正则表达式 Template for the replacement ...

  6. 【TypeScript】02 面向对象

    [联合类型] 联合类型(Union Types)可以通过管道(|)将变量设置多种类型,赋值时可以根据设置的类型来赋值. 注意:只能赋值指定的类型,如果赋值其它类型就会报错. var val:strin ...

  7. 删库了不用跑路!binlog恢复数据实操

    各位道友大家好呀! 想必道友们或多或少都听说过MySQL的binlog的作用,它记录了数据库整个的生命周期,可用于恢复数据或者从库同步数据. 那么如果发生了数据库误删,具体该怎样恢复数据呢? 下面就以 ...

  8. AI阅读助手ChatDOC:基于 AI 与文档对话、重新定义阅读方式的AI文献阅读和文档处理工具

    让 AI 真正成为你的生产力超级助手 AI 时代降临,我们需要积极拥抱 AI 工具 在过去的 2 个多月里,以 ChatGPT 为代表的 AI 风靡全球.随着 GPT 模型的不断优化,ChatGPT ...

  9. 推荐5款免费、开箱即用的Vue后台管理系统模板

    前言 在现今的软件开发领域,Vue凭借其高效.灵活和易于上手的特性,成为了前端开发的热门选择.对于需要快速搭建企业级后台管理系统的开发者而言,使用现成的Vue后台管理系统模板无疑是一个明智之举.本文大 ...

  10. 平衡树 -- Splay & Treap

    Treap & Splay学习笔记 前置知识 -- BST 二叉搜索树,一种比较好玩的数据结构,其实现原理是运用每个点的权值构建,其中满足这样的构造方式: 若 \(value > t[x ...