【Python】【动态规划】【最佳加法表达式】

问题:

输入一个数字组成的字符串,给m个加号,将所有加号任意放在字符串中中某位置,要求最终得到的加法表达式的结果最小。

例子:

输入:2

          123456 

输出:135

思路:

我们用加号的个数作为迭代的依据。创建两个二维数组。

第一个是cur_min[m][n]表示将m个+号放入前n个数字中。根据加法式子的构成我们可以得到两个条件。1.m=0,即+号个数为0时,剩下的所有前面数字组成的数就是结果. 2. n>m+1,数字的个数一定比加号多一个,不然加法式子不成立

第二个是nums[n][n]代表所有从n到n的数字的大小。比如123456中n[1][3] = 234

在计算过程中首先循环计算前1到n个数字中插入0个加号的大小,等于nums[0][i]

再逐渐加入+。每次加入加号,可以加入的位置都是在m到n-1,因为数字个数必须要比+的个数多1

迭代转换方程式: cur_min[m][n] = min(cur_min[i][j],cur_min[i-1][p]+nums[p+1][j])   for p = i 到 j

举例说明迭代转化方程式比如求4个数字1234插入两个加号的最小值。就要先循环算+,p=2 to 3,

p=2就是cur_min[i-1][p]=1+2;  nums[p+1][j] =34

p=3就是cur_min[i-1][p]=12+3和1+23中的最小的那个,即15;  nums[p+1][j] =4

找出最小就是19

代码:

def best_add(m,ints):
    nums = [[2**11 for i in range(len(ints))] for j in range(len(ints))]
    for i in range(len(ints)):
        nums[i][i] = ints[i]
    for i in range(len(ints)):
        for j in range(i+1,len(ints)):
            nums[i][j] = nums[i][j-1]*10+ints[j]
    cur_min = [[2**11 for i in range(len(ints))] for j in range(m+1)]
    for i in range(len(ints)):
        cur_min[0][i] = nums[0][i]
    for i in range(1,m+1):
        for j in range(len(ints)):
            for p in range(i,j):
                cur_min[i][j] = min(cur_min[i][j],cur_min[i-1][p]+nums[p+1][j])
    return cur_min[m][len(ints)-1]




def main():
    m = int(input())
    nums=list(str(input()))
    nums = [int(i) for i in nums]
    print(best_add(m,nums))


if __name__ == '__main__':
    main()

参考:https://blog.csdn.net/liushall/article/details/79282742

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值