动态规划算法及Java实例

动态规划算法的基本概念

动态规划算法是一种解决复杂问题的有效方法,它通过将大问题分解为小问题,然后逐个解决这些小问题,最终通过组合小问题的解来得到大问题的解。这种方法的特点是充分利用了问题的重叠子问题和最优子结构的特性,避免了重复计算,大大提高了算法的效率。

public class OneMoreClass {public int dynamicProgramming(int 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];}
}

以上是一个简单的动态规划算法的Java实现,我们定义了一个OneMoreClass类,其中的dynamicProgramming方法接受一个整数n作为参数,返回斐波那契数列的第n项。我们首先定义了一个数组dp,然后初始化dp[0]dp[1]。接下来,我们通过一个循环,计算出dp[i]的值,最后返回dp[n]

动态规划算法的适用问题类型非常广泛,包括序列对齐、路径规划、资源分配等等。然而,要想有效地应用动态规划算法来解决问题,我们还需要理解它的解题步骤,包括状态定义、状态转移方程的建立以及解决边界条件等。

动态规划算法的解题步骤

在我们理解了动态规划算法的基本概念后,接下来就要进入解题的步骤。在动态规划中,我们首先要定义状态。状态是我们解决问题的基础,它反映了问题在某一阶段的特征。比如在求解最长公共子序列问题中,我们可以定义dp[i][j]为字符串A[0...i]B[0...j]的最长公共子序列的长度。

int[][] dp = new int[oneMoreCount][oneMoreCount];

接下来,我们要建立状态转移方程。状态转移方程是动态规划的核心,它描述了状态之间的关系。在最长公共子序列问题中,如果A[i]等于B[j],那么dp[i][j]就等于dp[i-1][j-1]+1;否则,dp[i][j]就等于max(dp[i-1][j], dp[i][j-1])

if (A[i] == B[j]) {dp[i][j] = dp[i - 1][j - 1] + 1;
} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}

最后,我们要解决边界条件。边界条件是动态规划的起点,它为我们提供了初始状态。在最长公共子序列问题中,当ij等于0时,dp[i][j]就等于0。

for (int i = 0; i < oneMoreCount; i++) {dp[i][0] = 0;
}
for (int j = 0; j < oneMoreCount; j++) {dp[0][j] = 0;
}

通过以上三个步骤,我们就能够解决动态规划问题。然而,理论知识总是抽象的,下面我们将通过一个具体的Java案例,来展示如何在实际中实现动态规划算法。

Java中实现动态规划算法

在理解了动态规划算法的基本概念和解题步骤之后,我们将进入实战阶段,通过一个互联网电商系统中实际的Java案例,来具体展示如何在Java中实现动态规划算法,包括代码编写、调试和运行等过程。

假设我们的电商系统中有一个需求,需要通过动态规划算法来解决商品的最优购买组合问题。在这个问题中,我们有一系列的商品,每个商品都有自己的价值和价格,我们的目标是在有限的预算下,选择一些商品,使得这些商品的总价值最大。这是一个典型的背包问题,非常适合使用动态规划算法来解决。

首先,我们需要定义一个名为OneMoreGood的类,这个类的主要作用是存储商品的价值和价格信息。然后,我们需要定义一个二维数组dp,其中dp[i][j]表示在预算为j的情况下,前i个商品能够得到的最大价值。

class OneMoreGood {int price;int value;OneMoreGood(int price, int value) {this.price = price;this.value = value;}
}

接着,我们需要编写动态规划算法的主要逻辑。在这个过程中,我们需要遍历所有的商品,对于每一个商品,我们都需要考虑是否购买它。如果我们购买了这个商品,那么我们的预算就会减少,但是我们能够得到的价值会增加;如果我们没有购买这个商品,那么我们的预算和价值都不会变化。我们需要在这两种情况中选择一种,使得我们能够得到的价值最大。

public static int getMaxValue(OneMoreGood[] goods, int n, int m) {int[][] dp = new int[n + 1][m + 1];for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (j < goods[i - 1].price) {dp[i][j] = dp[i - 1][j];} else {dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - goods[i - 1].price] + goods[i - 1].value);}}}return dp[n][m];
}

在完成代码编写之后,我们需要进行调试和运行。我们可以通过编写一些测试用例,来验证我们的代码是否能够正确地解决问题。

public static void main(String[] args) {// 测试用例:最优的购买组合是购买第一个和第三个商品,总价值为7。OneMoreGood[] goods = new OneMoreGood[3];goods[0] = new OneMoreGood(1, 3);goods[1] = new OneMoreGood(2, 2);goods[2] = new OneMoreGood(1, 4);int n = goods.length;int m = 2;System.out.println(getMaxValue(goods, n, m));  // 输出应为7 
}

如果我们的代码能够通过所有的测试用例,那么我们就可以认为我们的代码是正确的。

总结

我们已经走过了动态规划算法的概念,解题步骤到实战的道路,从中我们可以看到,这是一种以空间换时间的策略,它通过存储子问题的解,避免了重复计算,从而提高了算法的效率。同时,我们也看到了动态规划算法的实用性,它可以解决各种实际问题,如商品的最优购买组合问题。

然而,动态规划并非万能的,它也有自己的局限性。比如,动态规划算法通常需要大量的内存空间来存储子问题的解,这对于内存资源有限的场合是一种挑战。此外,动态规划算法需要明确的状态转移方程,这对于一些没有明显最优子结构或重叠子问题的问题,可能会很难找到合适的状态转移方程。

在实际应用中,我们需要根据问题的具体情况,选择最合适的算法。有时候,我们可能需要对动态规划算法进行改进,比如使用滚动数组来减少内存使用,或者使用记忆化搜索来避免不必要的计算。

总的来说,动态规划算法是一种强大而灵活的工具,它为我们解决复杂问题提供了一种有效的方法。只要我们能够深入理解它的原理,并熟练掌握它的使用技巧,那么我们就能够在编程的道路上,走得更远,看得更高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/778520.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

篮球论坛系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 目录 1. …

Linux根据时间删除文件或目录

《liunx根据时间删除文件》和 《Linux 根据时间删除文件或者目录》已经讲述了根据时间删除文件或目录的方法。 下面我做一些补充&#xff0c;讲述一个具体例子。以删除/home目录下的文件为例。 首先通过命令&#xff1a; ls -l --time-style"%Y-%m-%d %H:%M:%S"…

Redis、Mysql双写情况下,如何保证数据一致

Redis、Mysql双写情况下&#xff0c;如何保证数据一致 场景谈谈数据一致性三个经典的缓存模式Cache-Aside Pattern读流程写流程 Read-Through/Write-Through&#xff08;读写穿透&#xff09;Write behind &#xff08;异步缓存写入&#xff09; 操作缓存的时候&#xff0c;删除…

【tensorflow框架神经网络实现鸢尾花分类】

文章目录 1、数据获取2、数据集构建3、模型的训练验证可视化训练过程 1、数据获取 从sklearn中获取鸢尾花数据&#xff0c;并合并处理 from sklearn.datasets import load_iris import pandas as pdx_data load_iris().data y_data load_iris().targetx_data pd.DataFrame…

ros2相关代码记录

1.ros2概述 ROS2&#xff08;Robot Operating System 2&#xff09;是一个用于机器人应用程序的开源软件框架。它是ROS&#xff08;Robot Operating System&#xff09;的下一代版本&#xff0c;旨在改进和扩展原始ROS的特性&#xff0c;以适应更广泛的机器人应用场景和需求。…

Unity 实现鼠标左键进行射击

发射脚本实现思路 分析 确定用户交互方式&#xff1a;通过鼠标左键点击发射子弹。确定子弹发射逻辑&#xff1a;每次点击后有一定时间间隔才能再次发射。确定子弹发射源和方向&#xff1a;子弹从枪口&#xff08;Transform&#xff09;位置发射&#xff0c;沿枪口方向前进。 变…

Qt扫盲-QAssisant 集成其他qch帮助文档

QAssisant 集成其他qch帮助文档 一、概述二、Cmake qch例子1. 下载 Cmake.qch2. 添加qch1. 直接放置于Qt 帮助的目录下2. 在 QAssisant中添加 一、概述 QAssisant是一个很好的帮助文档&#xff0c;他提供了供我们在外部添加新的 qch帮助文档的功能接口&#xff0c;一般有两中添…

八大技术趋势案例(虚拟现实增强现实)

科技巨变,未来已来,八大技术趋势引领数字化时代。信息技术的迅猛发展,深刻改变了我们的生活、工作和生产方式。人工智能、物联网、云计算、大数据、虚拟现实、增强现实、区块链、量子计算等新兴技术在各行各业得到广泛应用,为各个领域带来了新的活力和变革。 为了更好地了解…

QT QInputDialog弹出消息框用法

使用QInputDialog类的静态方法来弹出对话框获取用户输入&#xff0c;缺点是不能自定义按钮的文字&#xff0c;默认为OK和Cancel&#xff1a; int main(int argc, char *argv[]) {QApplication a(argc, argv);bool isOK;QString text QInputDialog::getText(NULL, "Input …

李宏毅【生成式AI导论 2024】第6讲 大型语言模型修炼_第一阶段_ 自我学习累积实力

背景知识:机器怎么学会做文字接龙 详见:https://blog.csdn.net/qq_26557761/article/details/136986922?spm=1001.2014.3001.5501 在语言模型的修炼中,我们需要训练资料来找出数十亿个未知参数,这个过程叫做训练或学习。找到参数后,我们可以使用函数来进行文字接龙,拿…

【数据分析面试】3.编写数据选取函数(Python)

题目 给定了一个名为 students_df 的学生数据表格 nameagefavorite_colorgradeTim Voss19red91Nicole Johnson20yellow95Elsa Williams21green82John James20blue75Catherine Jones23green93 编写一个名为 grades_colors 的函数&#xff0c;以选择仅当学生喜欢的颜色是绿色或…

2024最新Guitar Pro 8.1中文版永久许可证激活

Guitar Pro是一款非常受欢迎的音乐制作软件&#xff0c;它可以帮助用户创建和编辑各种音乐曲谱。从其诞生以来就送专门为了编写吉他谱而研发迭代的。 尽管这款产品可能已经成为全球最受欢迎的吉他打谱软件&#xff0c;在编写吉他六线谱和乐队总谱中始终处于行业领先地位&#x…

ESCTF-密码赛题WP

*小学生的爱情* Base64解码获得flag *中学生的爱情* 社会主义核心价值观在线解码得到flag http://www.atoolbox.net/Tool.php?Id850 *高中生的爱情* U2FsdG开头为rabbit密码,又提示你密钥为love。本地toolfx密码工具箱解密。不知道为什么在线解密不行。 *大学生的爱情* …

jira安装与配置

1. 环境准备 环境要求 1) JDK1.8以上环境配置 2) Mysql数据库5.7.13 3) Jira版本7及破解包 1.1 JDK1.8安装配置 1) 首先下载 JDK1.8&#xff0c; - 网址&#xff1a;https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html - windows64 版&am…

机器学习优化算法(深度学习)

目录 预备知识 梯度 Hessian 矩阵&#xff08;海森矩阵&#xff0c;或者黑塞矩阵&#xff09; 拉格朗日中值定理 柯西中值定理 泰勒公式 黑塞矩阵&#xff08;Hessian矩阵&#xff09; Jacobi 矩阵 优化方法 梯度下降法&#xff08;Gradient Descent&#xff09; 随机…

Pytorch的hook函数

hook函数是勾子函数&#xff0c;用于在不改变原始模型结构的情况下&#xff0c;注入一些新的代码用于调试和检验模型&#xff0c;常见的用法有保留非叶子结点的梯度数据&#xff08;Pytorch的非叶子节点的梯度数据在计算完毕之后就会被删除&#xff0c;访问的时候会显示为None&…

STM32CubeMX学习笔记28---FreeRTOS软件定时器

一、软件定时器简介 1 、基本概念 定时器&#xff0c;是指从指定的时刻开始&#xff0c;经过一个指定时间&#xff0c;然后触发一个超时事件&#xff0c;用户 可以自定义定时器的周期与频率。类似生活中的闹钟&#xff0c;我们可以设置闹钟每天什么时候响&#xff0c; 还能设置…

Unity | 工具类-UV滚动

一、内置渲染管线Shader Shader"Custom/ImageRoll" {Properties {_MainTex ("Main Tex", 2D) "white" {}_Width ("Width", float) 0.5_Distance ("Distance", float) 0}SubShader {Tags {"Queue""Trans…

2024.3.28学习笔记

今日学习韩顺平java0200_韩顺平Java_对象机制练习_哔哩哔哩_bilibili 今日学习p286-p294 继承 继承可以解决代码复用&#xff0c;让我们的编程更加靠近人类思维&#xff0c;当多个类存在相同的属性和方法时&#xff0c;可以从这些类中抽象出父类&#xff0c;在父类中定义这些…

Day24|回溯算法part01:理论基础、77. 组合

理论基础 回溯法&#xff0c;一般可以解决如下几种问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集问题&#xff1a;一个N个数的集合里有多少符合条件的子集排列问题&#xff1a;N个数…