最初在一個記事本上只有一個字符 'A'。你每次能夠對這個記事本進行兩種操做:
1.Copy All (複製所有) : 你能夠複製這個記事本中的全部字符(部分的複製是不容許的)。
2.Paste (粘貼) : 你能夠粘貼你上一次複製的字符。
給定一個數字 n 。你須要使用最少的操做次數,在記事本中打印出剛好 n 個 'A'。輸出可以打印出 n 個 'A' 的最少操做次數。
示例 1:java
輸入: 3
輸出: 3
解釋:
最初, 咱們只有一個字符 'A'。
第 1 步, 咱們使用 Copy All 操做。
第 2 步, 咱們使用 Paste 操做來得到 'AA'。
第 3 步, 咱們使用 Paste 操做來得到 'AAA'。code
說明:
1.n 的取值範圍是 [1, 1000] 。遞歸
若是每次Paste 'A',顯然操做次數就是n,那麼怎麼減小次數呢?這裏分爲兩種狀況:
1.n爲質數,不管剪切板裏有多少個‘A'(除了1個'A'的狀況),最終都沒法獲得n個'A',因此最少操做次數爲n;
2.n爲合數,獲得最少操做次數的狀況發生在已經有(n / i)個'A',其中i爲最小的能整除n的數(i大於1),說明只要操做i次就能獲得n個'A'。leetcode
class Solution { public int minSteps(int n) { if(n == 1) return 0; int i = 2; while(n % i != 0) i++; if(i == n) return n; return i + minSteps(n / i); } }
class Solution { public int minSteps(int n) { int res = 0; for (int i = 2; i <= n; i++) { while (n % i == 0) { res += i; n /= i; } } return res; } }
class Solution { public int minSteps(int n) { int[] dp = new int[n + 1]; for(int i = 2; i <= n; i++){ dp[i] = i; for(int j = 2; j < i; j++){ if(i % j == 0){ dp[i] = Math.min(dp[i], dp[i / j] + j); } } } return dp[n]; } }