LeetCode-【動態規劃】-只有兩個鍵的鍵盤
阿新 • • 發佈:2018-12-11
最初在一個記事本上只有一個字元 '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] 。
題解:這道題可以轉化成,給一個數字N,初始K=1,C=0然後只允許你有兩種操作: 1、K = K + C (paste) 2 、C = K (copy all) 如何操作可以使得最快得到N,當N>1時,其實這道題就是將N分解為M個數字的乘積,並且使M最小。
比如: 2 = 1 * 1 = 2 3 = 1 * 1 *1 = 3 4 = 2 * 2 = 1* 1* 1 *1 =4
class Solution { 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; } }
動規解法:接著上面分析,可以看出最後的結果是目標值的約數乘積,我們想要得到目標值用約數的最小數目,那就設dp[i]為值為i的約數乘積最少數目,dp[i]由它的前一個狀態得到,那它的前一個狀態的表示是不是使用當前約數時的最優解,對應寫為dp[i/j]+j;所以動態轉移方程為dp[i]=max(dp[i],d[i/j]+j)。
class Solution { public int minSteps(int n) { if(n==1) return 0; int[] dp=new int[n+1]; for(int i=1;i<=n;i++){ dp[i]=i; for(int j=1;j<=(int)(Math.sqrt(i));j++){ if(i%j==0) dp[i]=Math.min(dp[i],dp[i/j]+j); } } return dp[n]; } }