动态规划之拾取硬币

Posted AI小白奋斗史

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划之拾取硬币相关的知识,希望对你有一定的参考价值。

零.描述

Input: c[0],c[1],c[2]...c[n] 表示0到n到硬币的面值

Output:捡硬币使累计和最大.

要求:相邻两个硬币不能捡

比如

输入:5,1,2, 10, 6, 2

输出可能有以下情况:

5+10+2=17

2+6=8

1+10+2=13



二.算法:动态规划

对于序列C

(1) 将前i个硬币 C[0:i]当做子序列,其解定义为DP[i]=DP(C[0:i])。(拾捡累加和最大);

(2) 建立子问题之间的关系。只存在两种可能:

动态规划之拾取硬币

(3) 明确边界条件。DP[0]=C[0],规定DP[-1]=0

(4) 得到原问题的解,自底向上遍历表

(5)时间复杂度:子问题个数*每个子问题时间=n*c = O(n)



三.编程实现

def bottom_up_coins(c):
    dp = [None] * (len(c) + 1)
    dp[0] = 0  # 边界条件DP[-1]=0,由于python中[-1]代表最后一个元素,故用索引[0]代替
    dp[1] = c[0]  # 边界条件DP[0]=C[0]
    for i in range(2, len(c) + 1):
        dp[i] = max(dp[i - 2] + c[i - 1], dp[i - 1])  # 求解公式
    return dp

# 测试
coins = [5121062]
dp = bottom_up_coins(coins)
print('table is ', dp)
print('solution is ', dp[-1])


如果想知道拾取了哪些硬币,可以加入trace_back函数

def trace_back_coins(c, dp):
    select = []
    i = len(c)
    while i >= 1:
        if dp[i] > dp[i - 1]:
            select.append(c[i - 1])
            i -= 2
        else:
            i -= 1
    return select


END

往期回顾

以上是关于动态规划之拾取硬币的主要内容,如果未能解决你的问题,请参考以下文章

基本动态规划之硬币问题

Python之动态规划算法

破解大厂最难算命面试,动态规划之硬币兑换

破解大厂最难算法命面试:动态规划之硬币兑换

动态规划之找零钱问题

硬币问题-动态规划详解