赞
踩
笔记对应b站视频BV1bb411t7FK
有若干个数,从中选取一些数使得总和最大,要求是不可以选取相邻的数,问应当怎样选?
采用递归思想,当有i个数时,有两种选法,如果选择了第i个数,那么就不能选择第i-1个数,下一步就只能从第i-2个数及以前选择。但是如果不选第i个数,下一步就可以选第i-1个数,也就是将问题转化成了有i-1个数时的情况。由此,便可以按照递归的方式进行解题。
def find_max_sum(n_list):
if len(n_list) == 1:
return n_list[0]
if len(n_list) == 2:
return max(*n_list)
return max(find_max_sum(n_list[:-1]), n_list[-1]+find_max_sum(n_list[:-2]))
有若干种面值的硬币,按照面值由小到大排列。现在给出一个金额,不限制每种硬币拿取的数量,问怎样拿硬币,使得硬币的个数最少,而能够刚好达到需要的金额?
这个问题相当于先拿取一枚某一种面值的硬币,然后需要达到的金额就变成了总金额减去这枚硬币的金额,从而变成了一个子问题,可以用递归解决。以下是一个例子。
coins = [1,3,5]
def find(total):
if total < 0:
return 9999
if total == 0:
return 0
if total == 1:
return 1
return min(find(total-1)+1, find(total-3)+1, find(total-5)+1)
print(find(23))
对应B站视频BV1xb411e7ww
给定一个矩阵网格,一个机器人从左上角出发,每次可以向下或向右走一步,有多少种方式走到右下角?输出所有走到右下角的路径。
其中前一个问题应当使用动态规划,后一个问题使用递归来做(DFS)。
1、计数题
有多少种方式走到右下角
有多少种方法选出k个数使得和是sum
2、最值题
从左下角走到右上角路径的最大数字和
最长上升子序列长度
3、存在题
取石子游戏,先手是否必胜
能不能选出K个数使得和是sum
有三种硬币,2元、5元、7元,每种硬币都有足够多,用最少的硬币数凑出某个金额(如27)
看到“最少”字样,想到动态规划
状态在动态规划中的作用是定海神针,解题的时候需要开一个数组,数组的每个元素代表什么?(类似于设未知量)
确定状态需要两个意识:
最后一步:如,除去最后一枚硬币,剩余的硬币面值的总和一定是 s u m − a k sum-a_k sum−ak
子问题:现在的问题转化成了最少用多少枚硬币拼出 s u m − a k sum-a_k sum−ak的面值,这个问题与原问题类似,但是规模更小,这就叫子问题。
假定最优类的问题,只要找到最优子问题,就可以使用动态规划去尝试解题。
定义问题f,f(X)表示凑出面值X的最少硬币数,则有:
f(27) = min(f(27-2)+1, f(27-5)+1, f(27-7)+1)
首先,用递归来解题:
def f(X):
if X == 0:
return 0 # 0元钱只需要0枚硬币
res = float('inf') # 初始化使用无穷大, 同时暗含了负数与1的情况
if X >= 2:
res = min(f(X
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。