【精】leetcode

来源:互联网 发布:淘宝比较靠谱的韩代 编辑:程序博客网 时间:2024/04/28 19:32

题目

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

  1. Copy All: You can copy all the characters present on the notepad (partial copy is not allowed).
  2. 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 getn 'A'.

Example 1:

Input: 3Output: 3Explanation: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:

  1. 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[n];    }

解答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;}