当前位置: 首页 > news >正文

算法-动态规划

下面是使用 Java 实现动态规划(Dynamic Programming) 解决以下经典 DP 问题 的完整代码和说明:


✅ 1. 0-1 背包问题(Knapsack Problem)

问题描述:

给定 n 个物品,每个物品有重量 weights[i] 和价值 values[i],一个容量为 capacity 的背包。每个物品只能选一次,求能装入背包的最大总价值。

Java 实现:

public class Knapsack {public static int knapsack(int[] values, int[] weights, int capacity) {int n = values.length;int[][] dp = new int[n + 1][capacity + 1];for (int i = 1; i <= n; i++) {for (int w = 0; w <= capacity; w++) {if (weights[i - 1] <= w) {dp[i][w] = Math.max(dp[i - 1][w],dp[i - 1][w - weights[i - 1]] + values[i - 1]);} else {dp[i][w] = dp[i - 1][w];}}}return dp[n][capacity];}public static void main(String[] args) {int[] values = {60, 100, 120};int[] weights = {10, 20, 30};int capacity = 50;System.out.println(knapsack(values, weights, capacity)); // 输出 220}
}

✅ 2. 最长公共子序列(Longest Common Subsequence, LCS)

问题描述:

给定两个字符串 s1s2,找出它们的最长公共子序列(不连续,但顺序一致)。

Java 实现:

public class LCS {public static int longestCommonSubsequence(String s1, String s2) {int m = s1.length();int n = s2.length();int[][] dp = new int[m + 1][n + 1];for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (s1.charAt(i - 1) == s2.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[m][n];}public static void main(String[] args) {String s1 = "abcde";String s2 = "ace";System.out.println(longestCommonSubsequence(s1, s2)); // 输出 3}
}

✅ 3. 最长递增子序列(Longest Increasing Subsequence, LIS)

问题描述:

给定一个整数数组,找出其中 最长递增子序列 的长度(子序列元素顺序不变,但可以不连续)。

Java 实现:

public class LIS {public static int lengthOfLIS(int[] nums) {int n = nums.length;int[] dp = new int[n];int maxLen = 0;for (int i = 0; i < n; i++) {dp[i] = 1;for (int j = 0; j < i; j++) {if (nums[i] > nums[j]) {dp[i] = Math.max(dp[i], dp[j] + 1);}}maxLen = Math.max(maxLen, dp[i]);}return maxLen;}public static void main(String[] args) {int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};System.out.println(lengthOfLIS(nums)); // 输出 4(序列:2, 3, 7, 101)}
}

✅ 4. 编辑距离(Edit Distance)

问题描述:

给定两个字符串 word1word2,求将 word1 转换为 word2 所需的最少操作次数。操作包括:插入、删除、替换。

Java 实现:

public class EditDistance {public static int minDistance(String word1, String word2) {int m = word1.length();int n = word2.length();int[][] dp = new int[m + 1][n + 1];for (int i = 0; i <= m; i++) dp[i][0] = i;for (int j = 0; j <= n; j++) dp[0][j] = j;for (int i = 1; i <= m; i++) {for (int j = 1; j <= n; j++) {if (word1.charAt(i - 1) == word2.charAt(j - 1)) {dp[i][j] = dp[i - 1][j - 1];} else {dp[i][j] = 1 + Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]),dp[i - 1][j - 1]);}}}return dp[m][n];}public static void main(String[] args) {String word1 = "horse";String word2 = "ros";System.out.println(minDistance(word1, word2)); // 输出 3}
}

✅ 5. 矩阵链乘法(Matrix Chain Multiplication)

问题描述:

给定一个矩阵链 p[0..n],其中第 i 个矩阵的维度为 p[i-1] x p[i],求矩阵相乘所需的最小乘法次数。

Java 实现:

public class MatrixChainMultiplication {public static int matrixChainOrder(int[] p) {int n = p.length - 1;int[][] dp = new int[n][n];for (int l = 2; l <= n; l++) { // 链长for (int i = 0; i < n - l + 1; i++) {int j = i + l - 1;dp[i][j] = Integer.MAX_VALUE;for (int k = i; k < j; k++) {int cost = dp[i][k] + dp[k + 1][j] + p[i] * p[k] * p[j];dp[i][j] = Math.min(dp[i][j], cost);}}}return dp[0][n - 1];}public static void main(String[] args) {int[] p = {1, 2, 3, 4}; // 矩阵维度:1x2, 2x3, 3x4System.out.println(matrixChainOrder(p)); // 输出 18}
}

✅ 总结对比表

问题时间复杂度空间复杂度核心思想
背包问题O(n * capacity)O(n * capacity)选或不选
LCSO(m * n)O(m * n)末尾字符匹配
LISO(n²)O(n)逐个比较前面元素
编辑距离O(m * n)O(m * n)插入/删除/替换
矩阵链乘法O(n³)O(n²)分割点枚举

这些算法是 动态规划中的经典问题,掌握它们有助于理解状态转移、子问题划分、边界处理等核心思想。在实际开发中,这些算法常用于 字符串处理、资源分配、优化计算顺序 等场景。

http://www.dtcms.com/a/285885.html

相关文章:

  • MyBatis缓存实战指南:一级与二级缓存的深度解析与性能优化
  • 分布式短剧平台核心技术解析:CDN优化、AI推荐与多语言支付集成
  • 在 ASP.NET Core 和 JavaScript 中配置 WebSocket
  • Jfinal+SQLite处理 sqlite数据库执行FIND_IN_SET报错
  • .NET 8 Release Candidate 1 (RC1)现已发布,包括许多针对ASP.NET Core的重要改进!
  • 从复合变量到分组分析:piecewiseSEM 解析生态系统多因子交互作用
  • 深度剖析:最新发布的ChatGPT Agent 技术架构与应用场景
  • 专题:2025智能体研究报告|附70份报告PDF、原数据表汇总下载
  • NJU 凸优化导论(8) Lagrange Dual 拉格朗日对偶
  • Kotlin集合分组
  • 解决selenium元素定位不到疑难杂症
  • TCL 电视安装 APK 文件主要有 U 盘安装——仙盟创梦IDE
  • nastools继任者?极空间部署影视自动化订阅系统『MediaMaster』
  • echarts dataZoom 文本显示不完整
  • 响应式编程入门教程第六节:进阶?Combine、Merge、SelectMany 与错误处理
  • 【怜渠客】简单实现手机云控Windows电脑锁屏
  • MySQL中的锁有哪些
  • 【软件重构】如何避免意外冗余
  • 一文入门深度学习(以医学图像分割为例)
  • 【机器学习深度学习】LoRA 与 QLoRA:大模型高效微调的进阶指南
  • 【华为机试】70. 爬楼梯
  • 快速安装GitLab指南
  • mix-blend-mode的了解使用
  • git 介绍与使用教程
  • LP-MSPM0G3507学习--05管脚中断
  • 如何 ASP.NET Core 中使用 WebSocket
  • HTTP性能优化实战技术文章大纲
  • final 使用
  • 实现库存显示和状态按钮的Question
  • 数据统计模块后端架构解析:从Controller到SQL的ECharts数据对接实践