深入理解动态规划算法 | 凑整数

简介: 深入理解动态规划算法 | 凑整数

1. 问题描述

给定正整数n,找出所有不同的写法使得n为整数1,3,4的和。

如:n=5时,不同的写法有6种。


2. 问题分析

下面将介绍利用动态规划的思路来分析并解决问题。


第一步:对题目描述问题进行建模,将其转化为函数形式描述。

利用函数的思想对问题进行建模,令y=f(x)表示满足题目要求的正整数x有y种不同的写法。则f(5)=6表示的是满足题目要求的整数5共有6种不同的写法。由于函数的自变量取值为自然数,因此可以将函数表示为:y=f(n),其中n为自然数。


接下来的问题便是如何求解f(n)?


首先来考虑一个特例,那就是f(5)如何求解。


想象一下假设在我们面前有三堆整数,其中第一堆H1有若干个1,第二堆H2有若干个3,第三堆H3有若干个4。那么如何从这三堆数里面拿走若干个整数使得这些整数之和为5。


由于所有拿走的整数之和相加等于5,因此需要分多次拿。为简化问题的分析,接下来只考虑第一次拿数的情况。


第一种情况:第一次从第一堆H1中拿走一个1,接下来会发生什么。

第二种情况:第一次从第二堆H2中拿走一个3,接下来会发生什么。

第三种情况:第一次从第三堆H3中拿走一个4,接下来会发生什么。


请大家思考第一次拿数,除了上面之外,还有没有其他的情况?


答案显然是没有了,于是接下来便是分析这三种情况的解。


第一种情况

总和为5,第一次从H1中拿了一个1,5-1=4表示接下来还要凑够4。凑够整数4一共有多少种方法呢?答案就是f(4)。此处请大家回忆在开始处定义的函数f(n)的含义。因此第一种情况的解是f(4)。


第二种情况

总和为5,第一次从H2中拿了一个3,5-3=2表示接下来还要凑够2。凑够整数2一共有多少种方法呢?答案就是f(2)。此处请大家回忆在开始处定义的函数f(n)的含义。因此第一种情况的解是f(2)。


第三种情况

总和为5,第一次从H3中拿了一个4,5-4=1表示接下来还要凑够1。凑够整数1一共有多少种方法呢?答案就是f(1)。此处请大家回忆在开始处定义的函数f(n)的含义。因此第一种情况的解是f(1)。


以上完成了三种情况的求解分别是f(4)、f(2)、f(1),因此要求f(5)的解就是上面三种情况之和即f(5)=f(4)+f(2)+f(1)。


那如何求解f(4)、f(2)、f(1)呢?有了上面的分析,这个问题是不是很简单了。


因此得出一般的情况是:f(n) = f(n-1) + f(n-3) + f(n-4),而f(n-1)、f(n-3)f(n-4)又是按照同样的思路进行求解。分析问题的时候采取的是自上而下的思路,但是问题求解的时候,需要采取自下而上的方法,即先必须求得f(1)、f(2)f(3)f(4)的值,然后才能继续向后求解f(5)f(6)···f(n)。

f(1) = 1      (1)

f(2) = 1     (1,1)

f(3) = 2     (3), (1,1,1)

f(4) = 3     (4), (3,1), (1,1,1)


第三步:代码实现。

有了上面的细致分析,接下来就可以快速的写出python的代码。


import numpy as np


MAX_N = 10


# 给定正整数n,找出所有不同的写法使得n为整数1,3,4的和。

dp = np.zeros((MAX_N,))

dp[1] = 1

dp[2] = 1

dp[3] = 2

dp[4] = 3


for i in range(5, MAX_N):

   dp[i] = dp[i - 1] + dp[i - 3] + dp[i - 4]


print(dp)



结语

本文通过一个简单的凑整数案例,介绍了函数的基本思想,并将其应用到解决问题的思路中,帮助大家深入的理解函数。利用动态规划的思路分析问题、解决问题并最终完成了python代码的编写。

目录
相关文章
|
1月前
|
存储 算法
深入了解动态规划算法
深入了解动态规划算法
58 1
|
1月前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
4月前
|
算法 开发者 Python
惊呆了!Python算法设计与分析,分治法、贪心、动态规划...这些你都会了吗?不会?那还不快来学!
【7月更文挑战第10天】探索编程巅峰,算法至关重要。Python以其易读性成为学习算法的首选。分治法,如归并排序,将大问题拆解;贪心算法,如找零问题,每步求局部最优;动态规划,如斐波那契数列,利用子问题解。通过示例代码,理解并掌握这些算法,提升编程技能,面对挑战更加从容。动手实践,体验算法的神奇力量吧!
72 8
|
4月前
|
算法 Python
算法不再难!Python分治法、贪心、动态规划实战解析,轻松应对各种算法挑战!
【7月更文挑战第8天】掌握Python算法三剑客:分治、贪心、动态规划。分治如归并排序,将大问题拆解递归解决;贪心策略在每步选最优解,如高效找零;动态规划利用子问题解,避免重复计算,解决最长公共子序列问题。实例展示,助你轻松驾驭算法!**
70 3
|
16天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
32 2
|
1月前
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
69 2
动态规划算法学习三:0-1背包问题
|
1月前
|
算法
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
这篇文章介绍了动态规划算法中解决最大上升子序列问题(LIS)的方法,包括问题的描述、动态规划的步骤、状态表示、递推方程、计算最优值以及优化方法,如非动态规划的二分法。
66 0
动态规划算法学习四:最大上升子序列问题(LIS:Longest Increasing Subsequence)
|
1月前
|
算法
动态规划算法学习二:最长公共子序列
这篇文章介绍了如何使用动态规划算法解决最长公共子序列(LCS)问题,包括问题描述、最优子结构性质、状态表示、状态递归方程、计算最优值的方法,以及具体的代码实现。
136 0
动态规划算法学习二:最长公共子序列
|
1月前
|
存储 人工智能 算法
【算法——动态规划】蓝桥ALGO-1007 印章(C/C++)
【算法——动态规划】蓝桥ALGO-1007 印章(C/C++)
【算法——动态规划】蓝桥ALGO-1007 印章(C/C++)
|
1月前
|
存储 算法
动态规划算法学习一:DP的重要知识点、矩阵连乘算法
这篇文章是关于动态规划算法中矩阵连乘问题的详解,包括问题描述、最优子结构、重叠子问题、递归方法、备忘录方法和动态规划算法设计的步骤。
107 0
下一篇
无影云桌面