【用JAVA实现动态规划算法】1.背包问题2.最长公共子序列 3.最长上升子序列

动态规划 最长公共子序列 过程图解 1.基本概念       首先需要科普一下,最长公共子序列(longest common sequence)和最长公共子串(longest common substring)不是一回事儿。什么是子序列呢?即一个给定的序列的子序列,就是将给定序列中零个或多个元素去掉之后得到的结果。什么是子串呢?给定串中任意个连续的字符组成的子序列称为该串的子串。给一个图再解释一下:        如 阅读详情

1.背包问题(Knapsack Problem)

背包问题(Knapsack Problem)是一个经典的优化问题,通常描述为:给定一组物品,每种物品都有自己的重量和价值,在限定的总重量内,如何选择物品使得总价值最高。以下是一个0-1背包问题的Java实现,即每种物品只能选择0个或1个。

public class KnapsackProblem {

    // 物品类
    static class Item {
        int weight; // 重量
        int value;  // 价值

        public Item(int weight, int value) {
            this.weight = weight;
            this.value = value;
        }
    }

    // 0-1背包问题的动态规划解法
    public static int knapsack(Item[] items, int capacity) {
        int n = items.length; // 物品数量
        int[][] dp = new int[n + 1][capacity + 1]; // dp[i][j]表示前i个物品在容量为j的背包下能取得的最大价值

        // 初始化dp数组
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= capacity; j++) {
                if (i == 0 || j == 0) {
                    dp[i][j] = 0; // 没有物品可选或者背包容量为0时,价值为0
                }
            }
        }

        // 填充dp数组
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= capacity; j++) {
                // 如果第i个物品的重量大于背包容量j,则不选择该物品
                if (items[i - 1].weight > j) {
                    dp[i][j] = dp[i - 1][j];
                } else {
                    // 否则,比较选择第i个物品与不选择第i个物品两种情况下的最大价值
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - items[i - 1].weight] + items[i - 1].value);
                }
            }
        }

        // 返回最终的最大价值
        return dp[n][capacity];
    }

    public static void main(String[] args) {
        // 示例物品和背包容量
        Item[] items = {new Item(10, 60), new Item(20, 100), new Item(30, 120)};
        int capacity = 50;

        // 计算最大价值
        int maxValue = knapsack(items, capacity);
        System.out.println("背包容量为 " + capacity + " 时的最大价值为: " + maxValue);
    }
}

在上面的代码中,我们定义了一个Item类来表示物品,其中包含了weight(重量)和value(价值)两个属性。然后,我们使用动态规划的方法解决了0-1背包问题。在knapsack方法中,我们创建了一个二维数组dp来保存中间结果,其中dp[i][j]表示前i个物品在容量为j的背包下能取得的最大价值。最后,我们返回dp[n][capacity]作为最终的最大价值,其中n是物品数量,capacity是背包容量。

在main方法中,我们给出了一个示例物品数组和背包容量,并调用了knapsack方法来计算最大价值,并打印结果。

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

最长公共子序列(Longest Common Subsequence, LCS)是一个经典的计算机科学问题,用于找出两个或多个序列中的最长公共子序列。下面是一个使用Java实现的LCS算法,包括中文注释:

public class LongestCommonSubsequence {

    // 动态规划求解最长公共子序列
    public static int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length();
        int n = text2.length();

        // 创建一个二维数组dp,用于存储最长公共子序列的长度
        int[][] dp = new int[m + 1][n + 1];

        // 初始化dp数组的第一行和第一列,都为0
        for (int i = 0; i <= m; i++) {
            dp[i][0] = 0;
        }
        for (int j = 0; j <= n; j++) {
            dp[0][j] = 0;
        }

        // 填充dp数组
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    // 如果当前字符相等,则最长公共子序列长度加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 text1 = "ABCDEF";
        String text2 = "ACEF";
        System.out.println("最长公共子序列的长度为: " + longestCommonSubsequence(text1, text2));
    }
}

在这个代码中,我们使用了动态规划的思想。首先,我们创建了一个二维数组dp,其中dp[i][j]表示text1的前i个字符和text2的前j个字符的最长公共子序列的长度。然后,我们遍历两个字符串,如果当前字符相等,则最长公共子序列长度加1;如果当前字符不相等,则取上方和左方两个位置的最大值。最后,返回dp[m][n],其中m和n分别是两个字符串的长度,即为最长公共子序列的长度。

3.最长上升子序列(Longest Increasing Subsequence)

最长上升子序列(Longest Increasing Subsequence,LIS)是算法问题中非常经典的一类问题。以下是使用Java实现最长上升子序列算法的代码,并附带了中文注释:

public class LongestIncreasingSubsequence {

    // 动态规划求解最长上升子序列
    public static int lengthOfLIS(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        // dp[i] 表示以 nums[i] 结尾的最长上升子序列的长度
        int[] dp = new int[nums.length];
        
        // 初始化dp数组,每个元素的最长上升子序列至少包含自己
        for (int i = 0; i < nums.length; i++) {
            dp[i] = 1;
        }
        
        int maxLength = 1; // 最长上升子序列的长度
        
        // 遍历数组
        for (int i = 1; i < nums.length; i++) {
            // 遍历当前元素之前的所有元素
            for (int j = 0; j < i; j++) {
                // 如果当前元素大于前面的元素,则尝试更新dp[i]
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            // 更新最长上升子序列的长度
            maxLength = Math.max(maxLength, dp[i]);
        }
        
        return maxLength;
    }

    // 用于测试的方法
    public static void main(String[] args) {
        int[] nums = {10, 9, 2, 5, 3, 7, 101, 18};
        System.out.println("最长上升子序列的长度为: " + lengthOfLIS(nums));
    }
}

代码解释:

  • 我们使用一个数组 dp 来记录以每个元素为结尾的最长上升子序列的长度。
  • 初始化时,假设每个元素都是长度为1的子序列(因为它自己就是一个子序列)。
  • 遍历数组 nums,对于每个元素 nums[i],再遍历它之前的所有元素 nums[j](其中 j < i)。
  • 如果 nums[i] 大于 nums[j],则尝试更新 dp[i] 的值,因为 nums[i] 可以接在以 nums[j] 结尾的上升子序列后面,从而形成一个更长的上升子序列。
  • 更新 dp[i] 为 dp[j] + 1 和 dp[i] 之间的较大值。
  • 同时,我们用一个变量 maxLength 来记录遍历过程中遇到的最长上升子序列的长度。
  • 最后返回 maxLength 即可。

在 main 方法中,我们定义了一个示例数组 nums,并调用 lengthOfLIS 方法来计算最长上升子序列的长度,并将结果打印到控制台。

详解最长公共子序列问题(三种方法) C++分别利用三种动态规划解决最长公共子序列问题 阅读详情

相关推荐

数据结构与算法之最长公共子序列

数据结构与算法之最长公共子序列

weixin_47225948的博客 1833

最长公共子序列

动态规划:最长公共子序列,代码及其填写dp表格详解

北渡的博客 1万+

常见动态规划问题总结

最近毕业面临找工作的问题,在刷各大厂笔试题的时候发现大厂特别爱考一类问题,就是动态规划问题。于是决定将我见到的各类常见的动态规划问题做个总结,方便后期复习。 动态规划即Dynamic Programming,简称DP,初接触动态规划问题会觉得这类问题很抽象,晦涩难懂,不同的问题的求解思路也是千差万别,但是从本质上来看动态规划问题,最核心的思想就是将一个大的问题拆分成一个一个的子问题,通过定义问

mc695192383的博客 1万+

最长公共子序列LCS(动态规划)—详解

一.基本概念 1、 子序列(subsequence): 一个特定序列的子序列就是将给定序列中零个或多个元素去掉后得到的结果(不改变元素间相对次序)。例如序列<A,B,C,B,D,A,B><A,B,C,B,D,A,B>的子序列有:<A,B><A,B>、<B,C,A><B,C,A>、<A,B,C,D,A><A,B...

weixin_44023658的博客 1万+

蓝桥云课Java B组----第2篇----动态规划

TOC]本文面向已掌握Java基础语法的开发者,初学java者建议先夯实基础再阅读。再者,文章中所有的例题都在蓝桥官方题库网站里能查到,本文只提供编号,读者需输入例题编号自行查看题目,在学习例题过程当中,代码中的注释会给您提供帮助。

m0_53959137的博客 2120

动态规划之子序列问题

文章目录一、动态规划之子序列问题二、leetcode例题讲解子序列问题1. 子序列(不连续)300. 最长递增子序列1143. 最长公共子序列1035. 不相交的线2. 子序列(连续)674. 最长连续递增序列718. 最长重复子数组53. 最大子序和3. 编辑距离392. 判断子序列115. 不同的子序列583. 两个字符串的删除操作72. 编辑距离4. 回文串647. 回文子串516. 最长回文子序列 子序列问题是动态规划中一系列常见的问题,有多个种类,这里对动态规划的子序列问题进行汇总。 一、动态规划

小朱小朱绝不认输的博客 4118

动态规划之最长上升子序列,最长公共子序列,LIS,LCS模板(java)

动态规划之最长上升子序列,最长公共子序列,LIS,LCS;蓝桥杯;蓝桥杯备赛;动态规划;最长公共序列;最长子序列;算法;java;算法模板;

weixin_72499901的博客 612

python零基础入门到精通,python入门到精通教程

坚持到了这儿,恭喜你,表示你有做开发的潜力,其实我想说的上面的内容还是刚刚开始,刚开始大家不需要多么精通了解这些内容,除了Python方面的知识,每个部分掌握一点儿能进行基本开发就好,主要是不断练习,让自己跳出「舒适区」,进入「学习区」,但是又不进入「恐慌区」,不断给自己「喂招」。上述这份完整版的Python全套学习资料已经上传优快云官方,朋友们如果需要可以扫描下方二维码免费获取【保证100%免费】

YYmmsss的博客 3443

动态规划|最长公共子序列、最长上升子序列

文章目录LISLCS LIS 百练-2757 package 动态规划; import java.util.Scanner; /** * 單串 * @author DELL * */ public class 最长上升子序列 { static int n; static int[] data; static int[] record; public static void ...

My Blog 259

ArcGIS山体坡度、坡向分析

本篇文章主要记录自己在对山体坡向及坡度分析中的一些操作。

Belence_zhao的博客 7412

倍福TwinCAT3 OPC UA配置全流程:从安装到无密码访问(附常见问题解决)

本文提供了倍福TwinCAT3 OPC UA配置的完整实战指南,重点讲解如何实现无密码游客访问。从软件安装、授权配置、服务器初始化到深度排错,详细解析了配置流程中的关键步骤与常见陷阱,帮助工程师高效打通PLC与上位系统的数据通讯通道。

vulkan6gpu的博客 472

算法Day7:动态规划——背包、序列专题

动态规划 思路: 用一个表(常见数组)来记录所有已解子问题的答案。不管该子问题以后是否被用到,只要他被计算过就将结果填入表中,也叫打表法。 本阶段状态=(上一个阶段状态+上一个阶段决策) 应用: 一维:上升子序列模型 背包模型 二维:最长公共子序列问题 一般步骤: 确定状态(一是般先确定dp数组所表示的意义) 找到状态转移方程 思考:当前面临一个状态,它有可能是从哪儿来的? 状态转移方程要保证当...

JohnnyLin 1599

一、DMSP/OLS、NPP/VIIRS等夜间灯光数据能源碳排放空间化理论介绍

利用DMSP/OLS、NPP/VIIRS等夜间灯光数据开展能源碳排放空间化之前,需要区分与利用夜间灯光数据GDP空间化,两者操作流程并无较大区别,只是GDP空间化选择夜间灯光指数种类有比较多包括总灯光指数、平均灯光指数、综合灯光指数等,但是能源碳排放过程中通常只选择总灯光指数,其次能源碳排放空间化可能对于某些省份工业相对没有那么发达的区域,构建模型时候拟合效果比较差,也就是R方低一些或者显著性差。针对上述拟合度低的情况诸多学者前辈从多个方面开展研究进行提升。

端木宛白的博客家园 4924

今日刷三题(day10):最长公共子序列(二)+最长公共子串+最长上升子序列(一)

这一点我忽略掉了,直接返回dp[m][n]是错误的。

qq_66767167的博客 1239

基于非接触式微波雷达设计的睡眠监控系统_323

本项目设计了一种基于非接触式微波雷达的睡眠监控系统,通过高精度的生理信号采集与分析,帮助用户全面了解自身的睡眠状态和健康状况。系统采用60GHz频段的R60ABD1毫米波雷达模块,实现对人体呼吸频率、心率、活动状态、体动幅度等参数的非接触式测量;结合MLX90614红外体温传感器,能够实时监测人体体温。此外,系统通过蜂鸣器报警和数据上云功能,及时向用户反馈异常生理指标,确保健康风险早期预警。数据通过ESP8266-WIFI模块上传至华为云物联网平台,用户可通过Android手机APP和Windows上位机远

500

深入解析 Multi-Agent 协同决策机制与架构设计

让我们从一些基础定义开始,为后续的讨论建立共同的语言。在计算机科学和人工智能领域,智能体(Agent)是指一个能够感知环境、做出决策并执行动作的实体。智能体是任何可以通过传感器感知环境,并通过执行器作用于该环境的事物。atπstat​πst​sts_tst​是时刻ttt的环境状态(或智能体的观测)π\piπ是智能体的策略(Policy),即从状态到动作的映射ata_tat​是智能体在时刻ttt选择执行的动作多智能体系统(MAS)

AI天才研究院 541

矩阵最长上升子序列java_算法思想之动态规划(四)——最长公共子序列问题

前言今天我们继续讨论经典的动态规划问题之最长公共子序列问题。最长公共子序列问题问题描述给定两个字符串str1和str2,返回两个字符串的最长公共子序列的长度。例如,str1="1A2C3”,str2="B1D23”,”123"是最长公共子序列,那么两字符串的最长公共子序列的长度为3。问题分析假设两字符串str1和str2的长度分别为n和m。对于这类问题,我们一般可以构建一个大小的矩阵dp,其中代表...

weixin_32676541的博客 270

智能车图像处理2-入门级分析1 ---基础扫线

PS :入门级文章适合新手,如果已经有基础可以去看进阶篇文章。

taiyuezyh的博客 7752

凸多边形最优三角剖分动态规划_算法萌新如何学好动态规划(2)

本文是「动态规划」系列文章的第二篇,主要聚焦于常见线性 DP 模型的讲解。线性DP 是所有 DP 模型中最为常见与基础的模型,也是面试中最频繁考察的动态规划模型。文章一共分成四个部分,具体内容框架如下所示:一、动态规划解题思路回顾在正式开始线性 DP 的介绍前,我们需要回忆一下「算法萌新如何学好动态规划(一)」中的主要内容,即动态规划的解题思路。力扣(LeetCode):算法萌新如何学好动态规划(...

weixin_39754915的博客 141

【Agent实战】Anthropic Skills、MCP与LangGraph的工程实践

随着大语言模型(LLM)应用从简单的Chatbot向自主智能体(Autonomous Agents)演进,如何管理复杂的任务上下文、标准化的工具调用以及确定性的业务流程,成为了系统设计的核心挑战。Anthropic 推出的 Skills 规范,结合 Model Context Protocol (MCP) 与 Function Calling,为构建模块化、可扩展的 Agent 提供了全新的范式。

kakaZhui的博客 584

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Day1-2021年1月9日-【玩转算法面试0-1背包问题】

9-5 0-1背包问题 0-1背包问题 视频题 贪心算法:优先放入平均价值最高的物品。通过实际的案例对比,发现是不可以的。贪心算法是无法解决这个问题的。不是全局最优解。 0-1背包问题的状态转移方程。 F(n,c):将n个物品装进容量为c的背包,使得价值最大。 F(i,c)=max( F(i-1,c) , v(i) + F( i-1,c- w(i) ) ) F(i-1,c):第i个物品不放进背包中。 F( i-1,c- w(i) ) :第i个物品放进背包中,相应的,背包容量-物品i的重量w(i)。

renxanshou的博客 315

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

leetcode 动态规划——java实现

dp代表的什么,状态转移方程,填表

weixin_44040169的博客 1043

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【蓝桥杯Java组】带你刷爆常见动态规划模型

收录了动态规划的常见模型,最大子段和,最长公共子序列,最长递增子序列,编辑距离,背包问题...

Keep coding! 1903

动态规划入门

动态规划概念以及动态规划的基本问题:最大子串和,LCS,LIS,数塔,最大子矩阵和以及背包问题

周小末天天开心的博客 899

三种解法解决最长上升子序列(LIS)问题

LIS问题有三种解法: 解法一: 可以先将序列从小到大排序,然后求出排序后的序列和原来的序列的LCS长度就是最长上升子序列(LIS)长度 需要注意的是: 这种解法只能用于序列中没有重复元素的情况,因为要求子序列是严格上升的 .......

qq_64431576的博客 2531

Java语言常用的算法

分治算法是一种递归的算法思想,其基本思想是将一个大问题分解为若干个小问题,分别解决这些小问题,最后将小问题的解合并起来得到大问题的解。二分查找,也称为折半查找,它要求数据集合必须是有序的,它的基本思想是将数据集合分成两半,如果目标元素比中间元素小,就在前半部分继续查找,否则在后半部分继续查找,直到找到目标元素或数据集合为空。在实际应用中,分治算法也可以用来解决很多实际问题,比如在计算机图形学中,将一个大的图形对象分解成若干个小的三角形对象,每个小对象单独处理后再合并成一个大对象。

qq_45506362的博客 1万+
上一篇: 【用JAVA实现图论算法】1.最短路径算法(Dijkstra、Floyd-Warshall) 2.最小生成树算法(Prim、Kruskal法) 3.拓扑排序(Topological Sort)
下一篇: 【用java实现贪心算法】1.最小生成树(Prim算法、Kruskal算法) 2.单源最短路径(Dijkstra算法) 3.哈夫曼编码(Huffman Coding)
代码无疆
博客等级 码龄3年 4万+粉丝 305原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值