当前位置:   article > 正文

RMT的动态规划笔记_如果选择了i就不能选择i+1和i-1

如果选择了i就不能选择i+1和i-1

笔记1

笔记对应b站视频BV1bb411t7FK

1. 选数凑和问题

题目

有若干个数,从中选取一些数使得总和最大,要求是不可以选取相邻的数,问应当怎样选?

思路

采用递归思想,当有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]))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

笔记2

对应B站视频BV1xb411e7ww

引言:矩阵网格问题

给定一个矩阵网格,一个机器人从左上角出发,每次可以向下或向右走一步,有多少种方式走到右下角?输出所有走到右下角的路径。

其中前一个问题应当使用动态规划,后一个问题使用递归来做(DFS)。

动态规划题目特点

1、计数题
有多少种方式走到右下角
有多少种方法选出k个数使得和是sum

2、最值题
从左下角走到右上角路径的最大数字和
最长上升子序列长度

3、存在题
取石子游戏,先手是否必胜
能不能选出K个数使得和是sum

最值题:coin change问题

有三种硬币,2元、5元、7元,每种硬币都有足够多,用最少的硬币数凑出某个金额(如27)
看到“最少”字样,想到动态规划

解题:

1. 确定状态

状态在动态规划中的作用是定海神针,解题的时候需要开一个数组,数组的每个元素代表什么?(类似于设未知量)
确定状态需要两个意识:

最后一步:如,除去最后一枚硬币,剩余的硬币面值的总和一定是 s u m − a k sum-a_k sumak

  • 不关心前面的k-1枚硬币是怎么拼的,但确定面值的总和
  • 前面的硬币数一定要最少,一定是最少的

子问题:现在的问题转化成了最少用多少枚硬币拼出 s u m − a k sum-a_k sumak的面值,这个问题与原问题类似,但是规模更小,这就叫子问题。

假定最优类的问题,只要找到最优子问题,就可以使用动态规划去尝试解题。

定义问题f,f(X)表示凑出面值X的最少硬币数,则有:

f(27) = min(f(27-2)+1, f(27-5)+1, f(27-7)+1)
  • 1

首先,用递归来解题:

def f(X):
    if X == 0:
        return 0  # 0元钱只需要0枚硬币
    res = float('inf')  # 初始化使用无穷大, 同时暗含了负数与1的情况
    if X >= 2:
        res = min(f(X 
  • 1
  • 2
  • 3
  • 4
  • 5
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/389931
推荐阅读
相关标签
  

闽ICP备14008679号