vlambda博客
学习文章列表

编程 | 贪心算法 简介+Python代码实现


大家好,我是北海。今天来看一道贪心算法的题目。(题目与实现取自LeetCode)


给你数字k,请你返回和为k的斐波那契数字的最少数目,其中每个斐波那契数字都可以被使用多次。


斐波那契数字定义为:

F1 = 1

F2 = 1

Fn = Fn-1 + Fn-2 , 其中 n > 2 。

数据保证对于给定的 k ,一定能找到可行解。

 
   
   
 
示例:输入:k = 7输出:2 解释:斐波那契数字为:1,1,2,3,5,8,13,……对于 k = 7 ,我们可以得到 2 + 5 = 7 。
1

贪心算法简介


1、贪心算法的核心思想,就是求解问题时,选择当前看来最好的选择。


2、即不考虑整体最优,每一步得到的是当前局部最优解。


3、如果问题具有最优子结构性质,那么贪心算法最终能求得全局最优。


“最优子结构”是指一个问题的最优解包含其子问题的最优解。


例如:从北京到广东的最短路径,假设沿途经过了南京,那么这条最短路径里包括了从南京到广东的最短路径。


反例:总分第一的人,单科不一定是第一,所以“根据各科考试分数评选年级第一”这个问题就不具备最优子结构,不能使用贪心算法。


编程 | 贪心算法 简介+Python代码实现


2

Python代码


思路:

1、求出所有不超过k的斐波那契数

2、基于贪心算法思想,每次选取小于等于k的最大斐波那契数

3、将k减去该斐波那契数字

4、重复步骤2和3,直到k变为0,此时选取的斐波那契数字满足和为k且数目最少


class GreedAlgorithm:  # 创建类 def greed(self, k: int) -> int: # 定义函数        g = [11]    # 初始化斐波那契数列 # 下面的while循环实现步骤1        while g[-1] < k:  # f[-1]是指数组f中倒数第一个数            g.append(f[-1] + f[-2])  # 根据斐波那契数列定义,添加下一个斐波那契数        ans, i = 0, len(g) - 1       # 下面的while循环实现步骤2,3,4 while k:            if k >= g[i]:    # 实现步骤2,选取小于等于k的最大斐波那契数                k -= g[i]    # 实现步骤3,将k减去该斐波那契数字 ans += 1 # 计数 i -= 1        return ans           # 最后计数值就是“和为k的斐波那契数字的最少数目”


在数学上可以证明,只有每次不超过k的最大斐波那契数字,才能使得选取的斐波那契数字满足和为k且数目最少


这也是能够使用贪心算法的前提:具有最优子结构。


因此在数模竞赛中,如果你无法证明或者查找资料确定该问题具有最优子结构的话,不要轻易使用贪心算法!


注意是只要找到资料确定即可,无需在比赛论文中写出证明过程。


喜欢的话点击右下角的“赞”和“在看”,并分享给更多人~

-----------------------------------

回复 “群”,获得交流群群号,课件在群文件

回复“最新资料”,免费领取超全数模资料

回复“入门”,教你0基础小白入门数学建模