动态规划与贪心算法:核心区别与实例分析
动态规划与贪心算法:核心区别与实例分析
动态规划和贪心算法是计算机科学中用于解决优化问题的两种著名方法。它们各自的思路和应用场景有显著的区别,理解这些区别对解决相关问题至关重要。本文将详细探讨这两种算法的最优子结构、解法策略、适用场景,并通过具体的代码示例加以说明。
一、最优子结构
动态规划(Dynamic Programming, DP)
动态规划适用于具有最优子结构性质的问题。也就是说,问题的最优解可由其子问题的最优解组合而成。在 DP 中,通常会存储和复用这些子问题的结果,以避免重复计算,从而提高效率。
例子:斐波那契数列
动态规划可以用来高效地计算斐波那契数列。
public class Fibonacci {public int fib(int n) {if (n <= 1) return n;int[] dp = new int[n + 1];dp[0] = 0;dp[1] = 1;for (int i = 2; i <= n; i++) {dp[i] = dp[i - 1] + dp[i - 2]; // 状态转移}return dp[n];}
}
贪心算法(Greedy Algorithm)
贪心算法适用于通过局部最优选择来构造全局最优解的问题。在每一步,贪心算法都选择当前最优选项,而不考虑全局最优解,这种方法虽不保证最佳解,但在特定问题下可以得到全局最优解。
例子:找零问题
在给定硬币面额的情况下,贪心算法可以用来找零。
public class CoinChange {public int minCoins(int[] coins, int amount) {Arrays.sort(coins); // 先排序,贪心选择最大面额的硬币int count = 0;for (int i = coins.length - 1; i >= 0; i--) {while (amount >= coins[i]) {amount -= coins[i];count++;}}return count; // 最少硬币数量}
}
二、解法策略
动态规划的策略
- 自底向上:通过先解决较小的子问题,逐步构建出最终解决方案。
- 状态转移:定义状态的转换规则,从而构造 DP 表。
贪心算法的策略
- 自顶向下:逐步构造解决方案,每一步都选择当前认为最佳的选项。
- 局部最优选择:在当前状态下选择最优选项,构建全局解决方案。
三、适用场景
1. 动态规划的适用场景
动态规划通常适用于需要考虑所有可能选项的场景,典型问题包括:
- 背包问题
- 最长公共子序列
- 最短路径问题(如 Dijkstra 算法)
- 编辑距离
例子:最长公共子序列
public class LongestCommonSubsequence {public int lcs(String text1, String text2) {int[][] dp = new int[text1.length() + 1][text2.length() + 1];for (int i = 1; i <= text1.length(); i++) {for (int j = 1; j <= text2.length(); j++) {if (text1.charAt(i - 1) == text2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1] + 1;} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);}}}return dp[text1.length()][text2.length()];}
}
2. 贪心算法的适用场景
贪心算法则适用于那些局部选择能够构建全局解决方案的情况,例如:
- 活动选择问题
- 霍夫曼编码
- 最小生成树(Prim/Kruskal 算法)
例子:最小生成树(Kruskal 算法)
public class KruskalAlgorithm {public List<Edge> kruskal(List<Edge> edges, int numVertices) {Collections.sort(edges); // 按权重排序UnionFind uf = new UnionFind(numVertices);List<Edge> result = new ArrayList<>();for (Edge edge : edges) {if (uf.find(edge.src) != uf.find(edge.dest)) {uf.union(edge.src, edge.dest);result.add(edge); // 选择此边}}return result; // 返回最小生成树的边}
}
四、总结
-
动态规划:通过记忆化存储中间状态以减少计算量,适合状态具有重叠子问题的情况。它是解决复杂问题的强大工具。
-
贪心算法:通过在每一步选择中做出局部最优解,适合解决能够通过局部选择构建全局解决方案的问题。
在实际的应用中,选择使用动态规划还是贪心算法,取决于问题的性质及其最优解的结构。理解这两者的区别与联系是解决许多优化问题的关键所在。
相关文章:
动态规划与贪心算法:核心区别与实例分析
动态规划与贪心算法:核心区别与实例分析 动态规划和贪心算法是计算机科学中用于解决优化问题的两种著名方法。它们各自的思路和应用场景有显著的区别,理解这些区别对解决相关问题至关重要。本文将详细探讨这两种算法的最优子结构、解法策略、适用场景&a…...
.NET 公共语言运行时(Common Language Runtime,CLR)
.NET 的公共语言运行时(Common Language Runtime,CLR)是 .NET Framework 和 .NET Core 的核心组件,负责运行和管理 .NET 程序。CLR 提供了一个高效、安全和稳定的执行环境,支持多种编程语言并处理各种系统级的任务。下…...

SpringBoot使用TraceId日志链路追踪
项目场景: 有时候一个业务调用链场景,很长,调了各种各样的方法,看日志的时候,各个接口的日志穿插,确实让人头大。为了解决这个痛点,就使用了TraceId,根据TraceId关键字进入服务器查询…...
YOLO11 旋转目标检测 | OBB定向检测 | ONNX模型推理 | 旋转NMS
本文分享YOLO11中,从xxx.pt权重文件转为.onnx文件,然后使用.onnx文件,进行旋转目标检测任务的模型推理。 用ONNX模型推理,便于算法到开发板或芯片的部署。 本文提供源代码,支持不同尺寸图片输入、支持旋转NMS过滤重复…...
PCL 点云拟合 拟合空间直线
目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 设置RANSAC算法参数 2.1.2拟合直线模型 2.1.3 提取拟合直线内点 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇总(长期更…...
我的创作纪念日-20241112-感谢困难
我的创作纪念日-20241112-感谢困难 一、机缘二、收获1、积累2、感谢困难 三、日常四、成就五、憧憬 一、机缘 我之前有一个自己的私人博客,但是后来发现CSDN的功能更强大,更专业,所以我就把自己博客内容转到CSDN上面来了。 二、收获 1、积累…...

苍穹外卖05-Redis相关知识点
目录 什么是Redis? redis中的一些常用指令 value的5种常用数据类型 各种数据类型的特点 Redis中数据操作的常用命令 字符串类型常用命令: 哈希类型常用命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 在java中操作Redis 环境…...

unity 玩家和炸弹切线计算方式
脚本挂在炸弹上! using System.Collections; using System.Collections.Generic; using UnityEngine;public class TargetDetaction : MonoBehaviour {private Transform PlayerTF;private Transform bomb;private float radius;private string Player "Play…...
【MySQL】MySQL中的函数之REGEXP_LIKE
在 MySQL 中,REGEXP_LIKE() 函数用于检查一个字符串是否与正则表达式匹配。不过需要注意的是,REGEXP_LIKE() 并不是所有版本的 MySQL 都支持的函数。这个函数是在 MySQL 8.0 版本中引入的。 基本语法 REGEXP_LIKE(str, pat [, match_type ])str: 要测试…...

跟着尚硅谷学vue2—进阶版4.0—Vuex1.0
5. Vuex 1. 理解 Vuex 1. 多组件共享数据-全局事件总线实现 红线是读,绿线是写 2. 多组件共享数据-vuex实现 vuex 不属于任何组件 3. 求和案例-纯vue版 核心代码 1.Count.vue <template><div><h1>当前求和为:{{ sum }}</h1&…...

深度学习服务器租赁AutoDL
省钱绝招 #AutoDL #GPU #租显卡...

excel常用技能
1.基础技能 1.1 下拉框设置 a. 选中需要设置的列或单元格,数据 ---》 数据验证 b.验证条件 ---> 序列(多个值逗号隔开) 1.2 进度条百分比显示设置 开始 ---> 条件格式 --->新建规则--->编辑规则 1.3 相对引用和绝对引用…...
Mac电脑中隐藏文件(即以 . 开头的文件/文件夹)的显示和隐藏的两种方法
方法一:使用电脑快捷键,步骤如下: 1、点击一下桌面,用来激活 Finder ; 2、同时按下 Command Shift 点,即 【Command Shift . 】; 3、 打开可能包含此类文件的文件夹,比如磁盘…...

【Linux】:进程信号(信号概念 信号处理 信号产生)
✨ 眼里有诗,自向远方 🌏 📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂&#…...

Flink运行时架构以及核心概念
1.运行构架 1.提交作业后启动一个客户端进程,客户端解析参数(-d -t 等等),后进行封装由Actor通信系统提交,取消,更新任务给JobManager。 2.JobManager(进程)通信系统一个组件叫分发…...

用 Python 从零开始创建神经网络(五):损失函数(Loss Functions)计算网络误差
用损失函数(Loss Functions)计算网络误差 引言1. 分类交叉熵损失(Categorical Cross-Entropy Loss)2. 分类交叉熵损失类(The Categorical Cross-Entropy Loss Class)展示到目前为止的所有代码3. 准确率计算…...

[CKS] K8S RuntimeClass SetUp
最近准备花一周的时间准备CKS考试,在准备考试中发现有一个题目关于RuntimeClass创建和挂载的题目。 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[CKS…...

【Python爬虫实战】轻量级爬虫利器:DrissionPage之SessionPage与WebPage模块详解
🌈个人主页:易辰君-CSDN博客 🔥 系列专栏:https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、SessionPage (一)SessionPage 模块的基本功能 (二)基本使…...

计算机网络-2.1物理层
文章目录 通信的基础概念信源、信宿、信号、信道码元、速率、波特带宽(Hz) 奈奎斯特采样定律和香农采样定律编码&解码,调制&解调常用的编码方法常用的调制方法 传输介质1. 导向型传输介质2. 非导向型传输介质物理层接口的特性 物理层…...

纯血鸿蒙系统 HarmonyOS NEXT自动化测试实践
1、测试框架选择 hdc:类似 android 系统的 adb 命令,提供设备信息查询,包管理,调试相关的命令ohos.UiTest:鸿蒙 sdk 的一部分,类似 android sdk 里的uiautomator,基于 Accessibility 服务&…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...