LeetCode 650. 只有两个键的键盘

这是一道很有趣的题目,我们要在只能进行全部复制和粘贴操作的情况下做最少的操作次数,题目如下所示:
题目
这道题目从表面上看,这道题目似乎没有思路,我们应该在什么时候复制什么时候进行粘贴,这些细节都是很难处理的。所以我们可以不考虑这些细节,直接用动态规划的思想来分析这道题目,那么这道题目的核心就是求解出动态规划的递推方程。
首先我们想一下,在最普通的情况下,我们一个个地粘贴单字母‘A’,需要 i − 1 i-1 i1次粘贴和 1 1 1次复制,就是 i i i次操作。在我们可以整除某个约数 j j j 的时候,我们需要进行粘贴操作 ( i − j ) / j (i-j)/j (ij)/j 次,加上一次复制全部的操作,那就是 ( i − j ) / j + 1 (i-j)/j+1 (ij)/j+1 操作。所以我们可以得到动态规划的递推方程是: d p [ i ] = m i n ( d p [ i ] , d p [ j ] + ( i − j ) / j + 1 ) dp[i] = min(dp[i], dp[j]+(i-j)/j+1) dp[i]=min(dp[i],dp[j]+(ij)/j+1)
初始状态:
d p [ 1 ] = 0 dp[1] = 0 dp[1]=0
有了初始状态和动态规划的递推方程之后,我们可以写出代码:

class Solution(object):
    def minSteps(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 1 or n == 0:
            return 0
        dp = [_ for _ in range(n+1)]
        dp[1] = 0
        for i in range(2, n+1):
            dp[i] = i
            for j in range(1, i):
                if i % j == 0:
                    dp[i] = min(dp[i], dp[j] + (i - j)/j + 1)
        return dp[n]

所以,在这种细节难以分析的题目中,我们可以第一时间考虑用动态规划的思想来解决此类问题,重要的是我们要推导出动态规划的递推方程,这样的问题就可以迎刃而解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值