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

算法很美笔记(Java)——动态规划

解重叠子问题(当前解用到了以前求过的解)

形式:记忆型递归或递推(dp)

动态规划本质是递推,核心是找到状态转移的方式,也就是填excel表时的逻辑(填的方式),而后代码就按填表的逻辑写即可

可以先写递归解法,发现有很多重叠子问题时,再改dp

递归是从大规模到小规模,记忆型递归或dp都是小规模到大规模

大多数情况,题中要求什么,dp的值就代表什么,比如求最大长度,dp值就是最大长度

01背包问题

使用dfs,分为选和不选

递归

static int[] wi = {1,5,10,50,100,500};static int[] vi = {1,5,1,0,10,2};public static int t1(int w,int curr) {if (w <= 0)  return 0;if (curr == wi.length) return 0;if (w < wi[curr]) {//            重量不够,选不上了return t1(w,curr++);} else {
//        不选int choice1 = t1(w,curr++);//         选int choice2 =  vi[curr] + t1(w - wi[curr],curr++);
//            返回的是选择树当前层以下的所有层的最优解
//            与本层的选择无关,所以不会出现因为不知道选还是不选比较大而导致的w混乱return Math.max(choice1,choice2);}}

dp

因为后面的行需要借助第一行的值填,所以先初始化第一行,再填后面的

物品编号也就是当前可选什么物品,编号以前的物品都能选,比如编号2,则第1~3个物品都能选。但是我们因为是借助前面填过的数据填,所以实际上,只需要考虑当前编号的物品的选与不选,而编号以前的物品通过“借助前面填过的数据填”时就已经选上了。

价值计算= 当前物品价值 +(上一行,可用重量)----->选

              =(上一行,可用重量)----->不选

eg:

表格(2,3),当前容量为3,物品重量为3,要的起,所以分为选与不选。

选:价值 = 4 +(1,0 )= 4----->选

               =(1,3 )= 5----->不选

因为每格需要借助其他格的值填,所以不能只考虑w的容量,而是要考虑0~w 之间的所有容量,而最终所求,是右下角的那个值。因为我们计算的是考虑所有物品的情况下(最后一行),容量为w(最后一列)的最大利润

static int[] wi = {1,5,10,50,100,500};static int[] vi = {1,5,1,0,10,2};public static int _01bag(int w) {
//        二维数组存储数据
//        重量0~wint[][] arr = new int[wi.length][w + 1];
//        初始化第一行数据for (int j = 0; j < w + 1; j++) {if (j >= wi[0]) {
//                要的起arr[0][j] = vi[0];} else {
//                要不起arr[0][j] = 0;}}
//利用前一行填当前行for (int i = 1; i < wi.length; i++) {for (int j = 0; j < w + 1; j++) {if (j >= wi[i]) {
//                要的起
//                    要int get = vi[i] + arr[i - 1][j - wi[i]];
//                    不要int noGet = arr[i - 1][j];arr[i][j] = Math.max(get,noGet);} else {
//                要不起arr[i][j] = arr[i - 1][j];}}}
//        取右下角作为结果return arr[wi.length - 1][w];}

完全背包

比01背包多了个条件:每种物品可以挑选任意多件。

dp

仍然初始化第一行,用以供给后面计算

虽然一个物品可以选多次,但是我们还是只分为选和不选

当不选时,思路和01背包相同(剩余重量在上一行中寻找最优解)

当选时,选一个后,剩余重量在同行中寻找最优解。

因为只要是填过的就是已经找到最优解的了,同一个物品,我们只需要选一次,至于最终要选几次,交给同行的最优解来解决

钢条切割

第一刀可以切1+9、2+8、3+7……

1+9的第二刀切9,可以切成1+8、2+7……

2+8的第二刀切8,可以切成1+7、2+6……

也就是,固定前面的一段,切后面一段

因为如果两段都切会导致有很多重复结果比如2+8-->1+1 + 2+6和3+7-->1+2 + 1+6

因为是固定前面的一段,切后面一段,所以固定的的那一段长度可以直接得到价值,而只有后面那段价值不确定

递归

每切一刀就是一个递归,因为有不同切法,所以是for循环(控制切法)里写递归(控制刀数)

这样他们之间求max,就是结果(类似01背包问题的max,只不过01背包同层间都是两种选择,而本问题同层之间是不止两种)

static int[] v = {1 , 5 , 8 , 16 , 10 , 17 , 17 , 20 , 24 , 30};public static int cut(int x) {if (x == 0) return 0;
//        每刀切的长度1~10int maxSum = 0;for (int i = 1; i <= x; i++) {maxSum = Math.max(maxSum,(v[i-1] + cut(x - i)));}return maxSum;}

记忆型递归

这里会不止一次递归f(1)、f(2)……f(10),显然重复计算了

想改成只算一次,则用一个数组把这些值给记下来,当需要用的时候,如果有就直接用,没有就计算再存起来,以供后面计算使用

代码与直接递归类似

dp

画excel表为一个长度-价值最优表,不同长度的钢条对应不同价值

思路中,组合中第二段长度价值不确定,所以我们画了最优表,第二段价值直接取就行

最后求得长度为10的钢条的最大价值,return 价值

static int[] v = {1 , 5 , 8 , 16 , 10 , 17 , 17 , 20 , 24 , 30};public static int cut() {int[] sum = new int[11];sum[0] = 0;sum[1] = 1;for (int i = 3; i < 11; i++) {
//            curr初始为钢条不切,直接卖int curr = v[i - 1];for (int j = 1; j < i; j++) {int temp = v[j - 1] + sum[i - j];curr = Math.max(curr,temp);}sum[i] = curr;}return sum[10];}

数字三角形

The Triangle - POJ 1163 - Virtual Judge

在数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。三角形的行数大于1小于等于100,数字为 0 - 99输入格式:5 //表示三角形的行数 接下来输入三角形73 88 1 02 7 4 44 5 2 6 5
要求输出最大和

只能选左下,右下,而不是一层内可以随便选,所以无法一次性确定选什么最大,所以无法用贪心

那么就使用dfs把所有情况都列出来

可以看到,dfs会重复算中间的数,比如算第二层的3和8时,3算了f(1),8也算了f(1),所以用dp

从下往上填,最后一行没得选,直接初始化,其他行,找加起来更大的填上

static int[][] v = {{7},{3,8},{8,1,0},{2,7,4,4},{4,5,2,6,5},};public static int Triangle() {int[][] arr = new int[5][5];
//        System.out.println(arr[3].length);
//        初始化一行for (int i = 0; i < 5; i++) {arr[4][i] = v[4][i];}
//        填其他行for (int i = arr.length - 2; i >= 0; i--) {
//            列for (int j = 0; j < i + 1; j++) {arr[i][j] = Math.max(v[i][j] + arr[i+1][j],v[i][j] + arr[i+1][j+1]);}}return arr[0][0];}

最长公共子序列(LCS)

子数组只能像截取一段这样,是紧凑的

而子序列可以跳着来,只要前后顺序一致就行

比如AB34CA1BC2 则输出ABC

找出全部公共子序列,然后求max

有串S1 = AB34,S2 = A1BC2

让S1的每一个字母都作为一个子序列的开头

eg:让A作为开头,则去S2里找A,找到了的话,通过将后面未处理的序列进行递归和字符串拼接将后续子序列拼接出来。没找到则不用处理,这样max的时候就不会被取

这样处理完A开头的子序列后,处理B开头的子序列……

将这些子序列取长度max返回

用ArrayList存结果

for i :S1每个开头

        for j:S2 找相同字母

                找到了:当前字母+递归(剩余子串)

        if(上一个子序列.size()<当前子序列.size())res = 当前子序列

public static ArrayList<Character> str(String s1,String s2) {
//        让s1的,每一个字母开头ArrayList<Character> endRes = new ArrayList<>();for (int i = 0; i < s1.length(); i++) {ArrayList<Character> res = new ArrayList<>();
//            去s2找匹配的for (int j = 0; j < s2.length(); j++) {if (s1.charAt(i) == s2.charAt(j)) {res.add(s1.charAt(i));res.addAll(str(s1.substring(i + 1),s2.substring(j + 1)));break;}}if (res.size() > endRes.size()) {endRes = res;}}return endRes;}

最长上升子序列问题


有一个长为n的数列a0,a1,...,a(n-1)。请求出这个序列中最长的上升子序列的长度。上升子序列指的是对于任意的i&lt;j都满足ai&lt;aj的子序列。1≤n≤10000≤ai≤1000000输入n=5
a={4,2,3,1,5}
输出3(注:2,3,5)

因为是子序列,所以可以跳着取

暴力法

类似上一题的思路

以每一个数字开头,遍历向后找比这个数字大的数字,剩余数字用递归找

而后所有子序列求max 

dp

dp的每个值代表:以这个数字作为结尾,由它前面的数字组成的最长子序列的长度

curr是当前数字,

与前面每个数字做比较,自己较大,则curr的一个dp值等于 前面的数字的dp值+1,自己较小则urr的一个dp值等于 1(子序列只有自己,长度就是1)

再与更前面的数字作比较,求出一个dp值

…………

等与前面的每个数字作比较求出dp值后,取最大的dp值为最终dp值

求完所有dp值后,取最大的值作为结果返回

public static int maxLen(int[] a) {if (a.length == 0) return 0;int[] dp = new int[a.length];dp[0] = 1;for (int i = 1; i < dp.length; i++) {
//            子序列只有自己的时候的lengthint res = 1;
//            与前面的元素作比较for (int j = i - 1; j >= 0 ; j--) {
//                较小,子序列length就是1
//                较大if (a[j] < a[i]) {int temp = dp[j] + 1;
//                    取maxif (res < temp) {res = temp;}}}dp[i] = res;}return max(dp);}public static int max(int[] dp) {int maxVal = 0;for (int i = 0; i < dp.length; i++) {if (dp[i] > maxVal) {maxVal = dp[i];}}return maxVal;}public static void main(String[] args) {System.out.println(maxLen(new int[]{4,2,3,1,5}));}

相关文章:

算法很美笔记(Java)——动态规划

解重叠子问题&#xff08;当前解用到了以前求过的解&#xff09; 形式&#xff1a;记忆型递归或递推&#xff08;dp&#xff09; 动态规划本质是递推&#xff0c;核心是找到状态转移的方式&#xff0c;也就是填excel表时的逻辑&#xff08;填的方式&#xff09;&#xff0c;而…...

C++ ——继承

体现的是代码复用的思想 1、子类继承父类&#xff0c;子类就拥有了父类的特性&#xff08;成员方法和成员属性&#xff09; 2、已存在的类被称为“基类”或者“父类”或者“超类”&#xff1b;新创建的类被称为“派生类”或者“子类” 注意&#xff1a; &#xff08;1&#…...

LeetCode 热题 100 283. 移动零

LeetCode 热题 100 | 283. 移动零 大家好&#xff0c;今天我们来解决一道经典的算法题——移动零。这道题在LeetCode上被标记为简单难度&#xff0c;要求我们将数组中的所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。下面我将详细讲解解题思路&#xff0c;…...

游戏引擎学习第116天

回顾昨天的工作 本次工作内容主要集中在游戏开发的低级编程优化&#xff0c;尤其是手动优化软件渲染。工作目的之一是鼓励开发者避免依赖外部库&#xff0c;而是深入理解代码并进行优化。当前阶段正进行SIMD&#xff08;单指令多数据&#xff09;优化&#xff0c;使用Intel推荐…...

react(9)-redux

使用CRA快速创建react项目 npx create-react-app react-redux 安装配套工具 npm i reduxjs/toolkit react-redux 启动项目 在创建项目时候会出现一个问题 You are running create-react-app 5.0.0, which is behind the latest release (5.0.1). We no longer support…...

Linux内核实时机制7 - 实时改造机理 - 软中断优化下

Linux内核实时机制7 - 实时改造机理 - 软中断优化下 https://blog.csdn.net/u010971180/article/details/145722641以下分别以Linux4.19、Linux5.4、Linux5.10、Linux5.15 展开分析,深入社区实时改造机理的软中断优化过程。https://blog.csdn.net/weixin_41028621/article/det…...

企业知识管理平台重构数字时代知识体系与智能服务网络

内容概要 现代企业知识管理平台的演进呈现出全生命周期管理与智能服务网络构建的双重特征。通过四库体系&#xff08;知识采集库、加工库、应用库、评估库&#xff09;的协同运作&#xff0c;该系统实现了从知识沉淀、结构化处理到价值释放的完整闭环。其中&#xff0c;知识图…...

大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(3)

Paimon的下载及安装&#xff0c;并且了解了主键表的引擎以及changelog-producer的含义参考&#xff1a; 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join&#xff0c;集成mysql cdc等参考&#xff1a; 大数据组件(四)快速入门实时数据…...

SVN把英文换中文

原文链接&#xff1a;SVN设置成中文版本 都是英文&#xff0c;换中文 Tortoise SVN 安装汉化教程(乌龟SVN) https://pan.quark.cn/s/cb6f2eee3f90 下载中文包...

Ubuntu 的RabbitMQ安装

目录 1.安装Erlang 查看erlang版本 退出命令 2. 安装 RabbitMQ 3.确认安装结果 4.安装RabbitMQ管理界面 5.启动服务并访问 1.启动服务 2.查看服务状态 3.通过IP:port 访问界面 4.添加管理员用户 a&#xff09;添加用户名&#xff1a;admin&#xff0c;密码&#xff1…...

基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案

随着物联网和嵌入式技术的快速发展&#xff0c;嵌入式设备对实时音视频通信的需求日益增长。然而&#xff0c;传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题&#xff0c;难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点&#xff0c;本文将介…...

QML 实现一个动态的启动界面

QML 实现一个动态的启动界面 一、效果查看二、源码分享三、所用到的资源下载 一、效果查看 二、源码分享 工程结构 main.qml import QtQuick import QtQuick.Controls import QtQuick.Dialogs import Qt.labs.platformWindow {id:windowwidth: 640height: 400visible: truetit…...

智能预警系统标准化处理流程

在当今数字化时代,IT系统的稳定运行对企业的业务连续性至关重要。为了及时发现和响应系统异常,构建智能预警系统已成为许多企业的当务之急。但仅仅拥有预警系统还不够,我们还需要一套标准化的处理流程,确保问题能够高效、有序地得到解决。 © ivwdcwso (ID: u012172506) 一…...

Unity游戏制作中的C#基础(4)数组声明和使用

一、数组的声明 在 C# 中&#xff0c;声明数组有多种方式&#xff0c;每种方式都有其适用的场景&#xff0c;下面为你逐一详细介绍&#xff1a; 1. 直接初始化声明 这种方式直观且便捷&#xff0c;在声明数组的同时就为其赋初值&#xff0c;让数组从诞生之初就拥有了具体的数据…...

tailwindcss学习03

01 入门 02 vue中接入 03 工具类优先 准备 vue.svg <svg viewBox"0 0 40 40" xmlns"http://www.w3.org/2000/svg"> <defs> <linearGradient x1"50%" y1"0%" x2"50%" y2"100%" id"a"&…...

QML Component 与 Loader 结合动态加载组件

在实际项目中&#xff0c;有时候我们写好一个组件&#xff0c;但不是立即加载出来&#xff0c;而是触发某些条件后才动态的加载显示出来&#xff0c;当处理完某些操作后&#xff0c;再次将其关闭掉&#xff1b; 这样的需求&#xff0c;可以使用 Component 包裹着组件&#xff…...

Visual studio 2022 将打开文件的方式由单击改为双击

1. 打开vs2022&#xff0c;选择Tools -> Options打开Options设置页面 2. 在左侧依次展开Environment, 选择Tabs and Windows 3. 在右侧面板往下拖拽滚动条&#xff0c;找到Preview Tab section, unchecked "Preview selected files in Solution Explorer (Altclick t…...

网络工程师 (49)UDP协议

前言 UDP协议&#xff0c;即用户数据报协议&#xff08;User Datagram Protocol&#xff09;&#xff0c;是一种无连接的、不可靠的、面向报文的传输层通信协议。 一、基本特点 无连接性&#xff1a;UDP在发送数据之前不需要与目标设备建立连接&#xff0c;也无需在数据发送结束…...

了解大数据

一、大数据的特点&#xff1a; 1.大量 2.高速 3.多样 结构化数据和非结构化数据 4.低价值密度 二、大数据的应用场景&#xff1a;视频推荐、电商推荐等 三、大数据的技术发展脉络 阶段1&#xff1a;单机时代 阶段2&#xff1a;大数据时代-分布式处理 阶段3&#xff1a;实…...

命令模式

1. 命令模式简介 命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,从而使您可以用不同的请求对客户进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。命令模式的核心思想是将操作和操作的执行者解耦,使得操作可以独立于执行者进…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...