您的位置:首页 > 其它

【精】leetcode - 650. 2 Keys Keyboard 【动态规划 + 质数 & 非质数 + 简洁表达】

2017-08-05 15:36 543 查看

题目

Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step:

Copy All
: You can copy all the characters present on the notepad (partial copy is not allowed).
Paste
: You can paste the characters which are copiedlast time.
Given a number
n
. You have to get
exactly
n
'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get
n
'A'.

Example 1:

Input: 3
Output: 3
Explanation:
Intitally, we have one character 'A'.
In step 1, we use Copy All operation.
In step 2, we use Paste operation to get 'AA'.
In step 3, we use Paste operation to get 'AAA'.

Note:

The
n
will be in the range [1, 1000].

题意

最初在笔记本中只有一个字符“A”.你可以进行如下两种操作:

1.copy all:你可以将笔记本中的所有字母都进行复制(不支持复制部分)。

2.Paste: 将最后一次赋值的内容进行粘贴。

分析及解答

两种操作使得问题变得较为简单,因为状态空间因此被简化了。

所以,我们先来确定解决该问题需要用什么样的算法思想呢?

缩小规模】首先我们规模为n的问题,分解为小的问题进行求解。比如,求得到m (m < n)个“A”需要最少操作为多少呢?

确定依赖的关系、方向】假设我们已经得到了得到m个“A”的最少操作,那么我们能否断定规模为 n的问题  依赖于 规模为m 的问题呢?

事实上,是可能存在依赖关系的。比如 2m = n的情况。(这里【关键】只要可能存在依赖,那么我们就定义其为依赖

方向也是很重要的一方面,大的问题依赖于小的问题,而不是小的问题依赖于大的问题

不同规模的问题方向上的依赖性,我们可以确定:

该问题比较适合 动态规划类、分治法
算法求解。

排除分治法】而分治法适合将一个问题,分解成几个大小相等的问题。分治法在这里不适合,因为我们把问题分解成了底层的小问题,这些问题有重叠。

动态规划】当子问题存在重叠的时候,这就非常适合使用动态规划进行求解了,因为动态规划的备忘录就是为了避免子问题重叠而进行重复计算的。接下来给出相应的关键定义

dp[i]
: 表示得到 i 个 “A”需要的最小操作次数。

状态转移方程 dp[i] = Min ( dp[ i ] / dp[ j ] + dp[ j ] ) , dp[ i ] 需能整除 dp[j] 且 j < i

解答1:(原具体解答)

public int minSteps(int n) {
int[] dp = new int[n+1];

for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int j = i-1; j > 1; j--) {
if (i % j == 0) {
dp[i] = dp[j] + (i/j);
break;
}

}
}
return dp
;
}

解答2:(具体解答:原具体解答)

public int minSteps(int n) {
int res = 0;
for(int i=2;i<=n;i++){
while(n%i == 0){
res+= i;
n=n/i;
}
}
return res;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode medium dynamic