PigyChan_LeetCode 650. 只有两个键的键盘

650. 只有两个键的键盘

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

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

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

个人思路1.0:
设dp[n]为,组成n个字符所需要的最少操作数
经观察得

在这里插入图片描述

至此,可发现该题与数的最大公因数有关,n的最大公因数决定了剪切板上我们的字符串中,允许的最大长度。
设mcf为n的最大公因数:dp[n]=dp[mcf]+1C+(n/mcf-1)P (n>=2) (1)
在运用公式(1)时发现,每次运算并不用把dp数组从小到大都填满,例如dp[9]只需要dp[3]和dp[1]的值;
推测dp[64]只需要dp[32],dp[16],dp[8],dp[4],dp[2],dp[1];
只需要套娃不断寻找最大公因数,直到1为止4,并记录沿途值。
那就不用dp数组了,用递归自顶向下求解即可
代码1.0

class Solution {
public:
    vector<int> MCFArr;


    void getMCF(const int& num)
    {
        int maxMCF = 0;
        for (int i = 1; i <= num / 2; ++i)
        {
            if (num % i == 0)    maxMCF = i;
         }
        
        if (maxMCF != 1)
        {
            getMCF(maxMCF);
        }


        MCFArr.push_back(maxMCF);
    }


    int minSteps(int n) {
        if(n==1)
        {
            return 0;
        }
        getMCF(n);
        MCFArr.push_back(n);
        int len = MCFArr.size();
        vector<int> dp(len);


        dp[0] = 0;
        for (int i = 1; i < len; ++i)
        {
            dp[i] = dp[i - 1] + 1 + (MCFArr[i] / MCFArr[i - 1] - 1);
        }


        return dp[len - 1];
        
    }
};

通过递归(套娃)将n的最大公因数的最大公因数的…最大公因数,自小到大放到数组MCFArr中,最后加入n自己。创建与MCFArr等长的dp数组,用于存储下标对应的最大公因数的最少操作次数,再通过公式 dp[n]=dp[n-1]+1Copy+(MCFArr[n]/MCFArr[n-1]-1)Paste求解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值