动态规划——最优加法表达式

Posted coding易码当先

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划——最优加法表达式相关的知识,希望对你有一定的参考价值。

问题描述 



        有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中,值最小的那个表达式的值是多少 ?
动态规划(4)——最优加法表达式

问题分析    


        如果假设 min_sum(n, m) 表示使用在 n 个数字中插入 m 个加号所能形成的表达式的最小值,并且 num(i, j) 表示从原序列中第 i 个数字到第 j 个数字组成的整数。那么:


if m == 0:  # 如果一个加号都没有,那么自然最后的结果就是这 n 个数字组成的整数。
    min_sum(n,m) = num(1, n)
else if n < m + 1:  # 如果加号的个数比 n-1 大,那么不能构成加法表达式。
    min_sum(n,m) = 无穷大
else
    min_sum(n,m) = min{min_sum(i, m-1) + num(i+1, n)}, (i=m,..,n-1)

输入标题


原序列为 “12345”,有2个“+”。对于最后一个加号,其可以放的位置可以是以下这些情况:

1.(1234和1个“+”)+ 5;

2.(123和1个“+”)+ 45;

3.(12和1个“+”)+ 345;

那么此时的最小值就是上述三种情况的最小值。


代码实现


def num(i_th, j_th, se):
    """
    序列 se 中第 i 个数到第 j 个数组成的整数
    :param i_th:
    :param j_th:
    :param se: 序列
    :return: 构成的整数
    """

    return int(reduce(lambda x, y: x+y, map(str, se[i_th-1:j_th])))


def find_optimal(se, count):
    """
    给定一个序列 se 和 count 个加号,返回构成的加法表达式中最小值。
    :param se:
    :param count:
    :return:
    """

    min_sum = [[None for i in range(add_num + 1)] for i in range(len(se) + 1)]
    for m in range(count + 1):
        for n in range(1, len(se) + 1):
            if m == 0:
                min_sum[n][m] = num(1, n, se)
            elif m > n - 1:
                min_sum[n][m] = sys.maxsize
            else:
                min = sys.maxsize
                for i in range(m,n):
                    if min_sum[i][m-1] != sys.maxsize and min_sum[i][m-1] + num(i+1, n, se) < min:
                        min = min_sum[i][m-1] + num(i+1, n, se)
                min_sum[n][m] = min
    return min_sum[len(se)][count]



以上是关于动态规划——最优加法表达式的主要内容,如果未能解决你的问题,请参考以下文章

递推,动态规划(DP),字符串处理,最佳加法表达式

动态规划:熟练度练习(POJ 1458最佳加法表达式bailian2755POJ3624bailian1088)

动态规划:基本思路以及步骤

小烨收藏动态规划和贪心算法比较

动态规划之背包问题

动态规划(上):如何实现基于编辑距离的查询推荐?