算法题 - 数字游戏问题 - Python

189 篇文章 3 订阅

问题分析:

给定两个正数 mn0<=m<=n),现在求,从 m 开始,只能 加1,或者乘以2最后得到n最小操作次数

问题分析:

很显然是一个动态规划题目,首先考虑一个 m=1 的情况,不难得出 dp方程

         dp[1] = 0
n为偶数: dp[n] = min(dp[n-1]+1, dp[n/2]+1)
n为奇数: dp[n] = min(dp[n-1]+1, dp[(n-1)/2]+2)  # dp[(n-1)/2]+2  先乘再加

dp[n] 表示从 1n 最小操作次数。
那么,现在把 m 的值推广一下,其实思路和上面完全一样,但要注意两点:
(1)第一个值要初始化为 0
(2)在回头判断 dp[n/2]dp[(n-1)/2] 时,要注意数组算法越界,如果越界了很显然,只能做 +1操作;

Python3实现:

# @Time   :2018/08/23
# @Author :LiuYinxing


class Solution:
    def Solve(self, m, n):
        if m == n: return 0
        if abs(m-n) == 1: return 1
        if n < m: m, n = n, m  # 保持 m 是小的

        dp = [0] * (n-m+1)
        dp[1] = 1

        for i in range(2, (n-m+1)):
            if (i + m) % 2 == 0:  # 偶数的情况
                if (i + m) // 2 < m:  # 判断是否出界
                    dp[i] = dp[i - 1] + 1
                else:
                    dp[i] = min(dp[i - 1] + 1, dp[(i+m) // 2 - m] + 1)
            else:  # 奇数的情况
                if (i + m - 1) // 2 < m:
                    dp[i] = dp[i - 1] + 1
                else:
                    dp[i] = min(dp[i - 1] + 1, dp[(i + m - 1) // 2 - m] + 2)  # dp[(n-1)/2]+2
        print(dp)
        return dp[-1]


if __name__ == '__main__':
    solu = Solution()
    print(solu.Solve(7, 9))

声明:总结学习,有问题可以批评指正,大神可以略过哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值