动态规划算法(2)--最大子段和与最长公共子序列

目录

一、最大子段和

1、什么是最大子段和

2、暴力枚举

3、分治法

4、动态规划

二、最长公共子序列

1、什么是最长公共子序列

2、暴力枚举法

3、动态规划法

4、完整代码 


 

一、最大子段和

1、什么是最大子段和

        子段和就是数组中任意连续的一段序列的和,而最大子段和就是寻找子段和里最大的一个值。下面的解释中S[l,r]会用来表示l到r的子段和,l和r分别表示左值和右值。

        最大子段和一般有三种解决方案:暴力枚举法分治法动态规划法。下面将逐个介绍。

758a27854af049a2a71061694f22f443.png

2、暴力枚举

        暴力枚举就是遍历所有的子段和,寻找最大的子段和,时间复杂度eq?O%28n%5E3%29 。相对无脑,直接贴上代码。

    //暴力枚举法public static int maxsize_violate(ArrayList<Integer>arr,int left, int right){int max=-99999999;for(int i=left;i<=right;i++){int sum=0;for(int j=i;j<=right;j++){for(int k=i;k<=j;k++){sum+=arr.get(k);  //最大值来源}if(sum>max)max=sum;sum=0;}}return max;}

3、分治法

        将每个问题分解为三个小问题,左一半的子段和,右一半的子段和,(必须)跨区域的子段和。

        伪代码如下,可以看到左子段和与右子段和都是递归求解(3、4),跨区域的一定是左右两个子段和最大值的和(5、6、7),最后选择左子段和、右子段和、跨域子段和中最大的子段和(8、9)。

52b99b166ac14860a4ebc9626c2891af.png

        完整代码:

    //分治法public static int maxsize(ArrayList<Integer>arr, int left, int right){int sum=0,midSum=0,leftSum=0,rightSum=0;int center,s1,s2,lefts,rights;//左右相等,返回左值if (left==right){    sum=arr.get(left);}//否则,分治法else {center=(left+right)/2;leftSum=maxsize(arr,left,center);         //left,l+r/2     //左区间最大值rightSum=maxsize(arr,center+1,right);     //l+r/2+1,right  //右区间最大值//后面都是在计算跨区域最大值(必须跨区域),一定是左区间贴近边界的最大值加右区间贴近边界的最大值相加。s1=0;lefts=0;                             //s1存左侧区间最大值,lefts作为tempfor (int i=center;i>=left;i--){lefts+=arr.get(i);if (lefts>s1){s1=lefts;}}s2=0;rights=0;                             //s2存右侧区间最大值,rights作为temp               for (int j=center+1;j<=right;j++){rights+=arr.get(j);if (rights>s2){s2=rights;}}midSum=s1+s2;                              //中间跨域的等于左侧加右侧的if (midSum<leftSum){sum=leftSum;}else {sum=midSum;}if (sum<rightSum){sum=rightSum;}}return sum;}

4、动态规划

        动态规划法是自底向上推导,假设eq?a_i为第i个数,eq?b_i为包含最后一个数eq?a_i的连续子段和,sum为最大子段和。

        建立于下面图这个关系,假设已经有eq?a_ieq?a_%7Bj-1%7D的子段和eq?b_%7Bj-1%7D,那么加入后一个eq?a_j生成eq?b_j只有两种可能:

(1)eq?b_%7Bj-1%7D%5Cleqslant%200,那么eq?b_j%3Da_j

(2)eq?b_%7Bj-1%7D%3E0,那么eq?b_j%3Db_%7Bj-1%7D&plus;a_j

        对于eq?1%5Cleqslant%20j%5Cleqslant%20n的每一个eq?b_j,都要与sum取最大值,保证sum为eq?b_1eq?b_j中最大的值,返回sum。

5728b43fe8a94a65a0115e6a832184b9.png

        完整代码: 

    //动态规划法public static int maxsum(ArrayList<Integer>arr, int n){int sum=-999999;int b=0;for(int i=0;i<=n;i++){if(b>0)b+=arr.get(i);else    b=arr.get(i);if(b>sum)sum=b;}return sum;}

二、最长公共子序列

1、什么是最长公共子序列

        子序列是指序列中任意不一定连续但顺序的若干个字符组成的序列。如下图中Z1={B,C,A}为X的子序列,B,C,A三个字符在X中顺序出现,且不一定连续。

        公共子序列就是指两个序列之间存在一个共同的子序列,而我们就是要找到最长的一个公共子序列。

9afd433e7cc5406bb74eed774fad9691.png

2、暴力枚举法

        暴力枚举法,不仅占用了相当大的内存存放所有子序列,和所有公共子序列,而且浪费了巨大的时间,时间复杂度指数级eq?O%28n2%5Em%29

fd264a432b4541b988ab67a2838ec25e.png

3、动态规划法

        动态规划法仍然是这种自底向上的算法,讨论前一项的最长公共子序列通过比较两个序列下一个值,判定是否进入子序列。动态规划法的时间复杂度为O(mn)

554b804b5a8344cbb0c62269cd2029cf.png

        使用c[i][j]数组记录eq?x_jeq?y_j的最长公共子序列长度, b[i][j]数组记录子序列的产生情况。c数组存在下面的递归结构成立,与b数组的关系如下,根据这个递推式,可以写出c和b数组的生成函数。

9e797ea0c8e84be5a0f1caeffb7a2336.png

c[i][j]=c[i-1][j-1]+1

b[i][j]=1               

↖                  

c[i][j]=c[i-1][j]

b[i][j]=2

c[i][j]=c[i][j-1]

b[i][j]=3

 

如何构造最长子序列?

         就是根据b数组的指引,倒推子序列,所有b[i][j]=1,也就是b数组指引为左上箭头的,都是公共序列的值,将他们按顺序串接就得到了最大子序列。

cdd4e6e80b68495583118cc6db6aeb6c.png

        注意一个问题,X序列是y轴方向的,Y序列是x轴方向的。 

4、完整代码

//最长公共子序列
import java.util.Scanner;
public class LCS {public static void main(String [] args){String x=new Scanner(System.in).nextLine();String y=new Scanner(System.in).nextLine();int m=x.length();int n=y.length();int [][]c=new int[m+1][n+1];int [][]b=new int[m+1][n+1];LCSLength(x, y, c, b);for(int i=0;i<m+1;i++){for(int j=0;j<n+1;j++){System.out.print(c[i][j]);System.out.print("\t");}System.out.println("");}BuildLCS(m,n,x,b);}//最长公共子序列生成c和b数组public static void LCSLength(String x,String y,int [][]c,int [][]b){int i,j;int m=x.length();int n=y.length();for(i=0;i<m+1;i++)c[i][0]=0;for(i=0;i<n+1;i++)c[0][i]=0;for(i=1;i<m+1;i++){for(j=1;j<n+1;j++){if(x.charAt(i-1)==y.charAt(j-1)){c[i][j]=c[i-1][j-1]+1;b[i][j]=1;}else if(c[i-1][j]>=c[i][j-1]){c[i][j]=c[i-1][j];b[i][j]=2;}else{c[i][j]=c[i][j-1];b[i][j]=3;}}}}//构造最长公共子序列public static void BuildLCS(int i,int j,String x,int[][]b){if(i==0|j==0){return;}if(b[i][j]==1){BuildLCS(i-1, j-1, x, b);System.out.print(x.charAt(i-1));}else if(b[i][j]==2){BuildLCS(i-1,j,x,b);}else{    BuildLCS(i, j-1, x, b);}}
}

 

 

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

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

相关文章

阿里云服务器方升架构、自研硬件、AliFlash技术创新

阿里云服务器技术创新&#xff1a;服务器方升架构及自研硬件、自研存储硬件AliFlash和阿里云异构计算加速平台&#xff0c;阿里云百科分享阿里云服务器有哪些技术创新&#xff1a; 目录 服务器技术创新 服务器方升架构及自研硬件 自研存储硬件AliFlash 阿里云异构计算加速…

【Excel】快速提取某个符号前面的数据内容

【问题描述】 在使用excel整理数据过程中&#xff0c;经常与需要调整数据后&#xff0c;进行使用。 例如凭证导出后&#xff0c;科目列是包含科目编码和科目名称的。 但由于要将数据复制到其他的导入模板上使用&#xff0c;对应的模板只需要科目编码&#xff0c;不需要科目名称…

常说的I2C协议是干啥的(电子硬件)

I2C&#xff08;Inter-Integrated circuit&#xff09;协议是电子传输信号中常用的一种协议。 它是一种两线式串行双向总线&#xff0c;用于连接微控制器和外部设备&#xff0c;也因为它所需的引脚数只需要两条&#xff08;CLK和DATA&#xff09;&#xff0c;硬件实现简单&…

Acwing 906. 区间分组

Acwing 906. 区间分组 知识点题目描述思路讲解代码展示 知识点 贪心 题目描述 思路讲解 这段代码是用来维护一个最小堆&#xff0c;以确保右边界不相交的区间被正确地保留在堆中。让我详细解释这段代码&#xff1a; heap.empty()&#xff1a;这个条件检查最小堆 heap 是否为…

【牛客网】JZ39 数组中出现次数超过一半的数字

题目 思路 思路1 将数组排序,再保证有结果的情况下,此时数组中间的数字就是想要的结果 思路2 在保证有结果的情况下,此时数组的的众数是数组长度的一半以上 所以我们可以通过抵消的做法来找到最终的结果 我们可以从头遍历这个数组,如果两个数不相同,则消去这两个数,最坏的…

Bug:elementUI样式不起作用、Vue引入组件报错not found等(Vue+ElementUI问题汇总)

前端问题合集&#xff1a;VueElementUI 1. Vue引用Element-UI时&#xff0c;组件无效果解决方案 前提&#xff1a; 已经安装好elementUI依赖 //安装依赖 npm install element-ui //main.js中导入依赖并在全局中使用 import ElementUI from element-ui Vue.use(ElementUI)如果此…

C++笔记之环形队列

C笔记之环形队列 code review! 文章目录 C笔记之环形队列1.概念I——摘自 https://mp.weixin.qq.com/s/HUn9TF09RZ-UJKYPR5ZXhA2.概念II——摘自 http://t.csdnimg.cn/72bng3.概念III—— 摘自https://mp.weixin.qq.com/s/9Ga502p1DLcc6o75JBQlDg4.概念IV—— 摘自https://mp…

基于SSM的网上药品售卖系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Django之模板

一&#xff09;模板&#xff08;T&#xff09; 什么时候会使用模板呢&#xff1f; 仅对于Django这个框架来说&#xff0c;因为其是默认前后端不分离的框架&#xff08;前后端不分离值开发时前后端的代码在一起&#xff0c;不通过接口的方式连接&#xff0c;通过模板渲染的方式…

Ubuntu 20.04 安装部署 TiDB DM v7.3.0 集群【全网独家】

文章目录 测试环境说明TiDB 单机环境部署DM 集群部署1. 免密设置2. 组件下载3. DM 配置文件模板获取4.DM 配置文件设置5.部署与启动 DM 集群 前言&#xff1a; 放眼全网&#xff0c;我找不出一篇在 Ubuntu 里面搭建 DM 集群的文章&#xff0c;虽然 TiDB 官方推荐使用 CentOS 系…

多线程 - 阻塞式队列

阻塞队列 阻塞队列,也是一个队列 ~~ 先进先出 实际上有一些特殊的队列,不一定非得遵守先进先出的 ~~ 优先级队列(PriorityQueue) 阻塞队列,也是特殊的队列,虽然也是先进先出的,但是带有特殊的功能: 阻塞 如果队列为空,执行出队列操作,就会阻塞.阻塞到另一个线程往队列里添加元…

gitee 远程仓库操作基础(二)

(1&#xff09;clone远端仓库,本地建立分支推送 (基于远程仓库版本库 本地建立分支开发新功能) git clone gitgitee.com:xxxxx/alsa_test.git git remote add origin gitgitee.com:xxxxx/alsa_test.git进入clone过后路径代码,查看本地分支,发现该项目远程仓库有很多分支 基于…

分布式文件存储系统Minio实战

分布式文件系统应用场景 互联网海量非结构化数据的存储需求电商网站&#xff1a;海量商品图片视频网站&#xff1a;海量视频文件网盘 : 海量文件社交网站&#xff1a;海量图片 1. Minio介绍 MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存…

【JVM】第四篇 垃圾收集器ParNewCMS底层三色标记算法详解

导航 一. 垃圾收集算法详解1. 分代收集算法2. 标记-复制算法3. 标记-清除算法4. 标记-整理算法二. 垃圾收集器详解1. Serial收集器2. Parallel Scavenge收集器3. ParNew收集器4. CMS收集器三. 垃圾收集底层三色标记算法实现原理1. 垃圾收集底层使用三色标记算法的原因?2. 垃圾…

[Linux 基础] 一篇带你了解linux权限问题

文章目录 1、Linux下的两种用户2、文件类型和访问权限&#xff08;事物属性&#xff09;2.1 Linux下的文件类型2.2 基本权限2.3 文件权限值的表示方法&#xff08;1&#xff09;字符表示方法&#xff08;2&#xff09;8进制数值表示方法 2.4 文件访问权限的相关设置方法(1) chm…

javaee SpringMVC中json的使用

jsp <%--Created by IntelliJ IDEA.User: 呆萌老师:QQ:2398779723Date: 2019/12/6Time: 15:55To change this template use File | Settings | File Templates. --%> <% page contentType"text/html;charsetUTF-8" language"java" %> <%St…

json能够存储图片吗?

JSON 本身并不适合存储图片&#xff0c;因为它是一种轻量级的数据交换格式&#xff0c;易于阅读和编写&#xff0c;同时也易于机器解析和生成。JSON 数据格式简单&#xff0c;只包含键值对&#xff0c;因此它主要用于存储和传输文本数据。 然而&#xff0c;你可以将图片转换为 …

《数据结构、算法与应用C++语言描述》-栈的应用-列车车厢重排问题

列车车厢重排问题 一列货运列车有 n 节车厢&#xff0c;每节车厢要停靠在不同的车站。假设 n个车站从 1 到n 编号&#xff0c;而且货运列车按照从n到1的顺序经过车站。车厢的编号与它们要停靠的车站编号相同。为了便于从列车上卸掉相应的车厢&#xff0c;必须按照从前至后、从…

【吞噬星空】连播两集,尼赫鲁对徐欣动手,罗峰修分身强势复仇

Hello,小伙伴们&#xff0c;我是小郑继续为大家深度解析吞噬星空资讯。 吞噬星空动画第四季定档之后&#xff0c;官方真的是太宠粉了&#xff0c;每天都会公布全新预告情报&#xff0c;无论是外星人物角色&#xff0c;亦或者宇宙星球建模&#xff0c;那都是相当的炸裂。如今更…

Leetcode 450. 删除二叉搜索树中的节点

文章目录 题目代码&#xff08;10.2 首刷看解析&#xff09; 题目 Leetcode 450. 删除二叉搜索树中的节点 代码&#xff08;10.2 首刷看解析&#xff09; class Solution { public:TreeNode* deleteNode(TreeNode* root, int key) {if(!root)return root;if(root->val <…