算法很美笔记(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)
子数组只能像截取一段这样,是紧凑的
而子序列可以跳着来,只要前后顺序一致就行
比如AB34C和A1BC2 则输出ABC
找出全部公共子序列,然后求max
有串S1 = AB34C ,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<j都满足ai<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)——动态规划
解重叠子问题(当前解用到了以前求过的解) 形式:记忆型递归或递推(dp) 动态规划本质是递推,核心是找到状态转移的方式,也就是填excel表时的逻辑(填的方式),而…...
C++ ——继承
体现的是代码复用的思想 1、子类继承父类,子类就拥有了父类的特性(成员方法和成员属性) 2、已存在的类被称为“基类”或者“父类”或者“超类”;新创建的类被称为“派生类”或者“子类” 注意: (1&#…...
LeetCode 热题 100 283. 移动零
LeetCode 热题 100 | 283. 移动零 大家好,今天我们来解决一道经典的算法题——移动零。这道题在LeetCode上被标记为简单难度,要求我们将数组中的所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。下面我将详细讲解解题思路,…...
游戏引擎学习第116天
回顾昨天的工作 本次工作内容主要集中在游戏开发的低级编程优化,尤其是手动优化软件渲染。工作目的之一是鼓励开发者避免依赖外部库,而是深入理解代码并进行优化。当前阶段正进行SIMD(单指令多数据)优化,使用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…...
企业知识管理平台重构数字时代知识体系与智能服务网络
内容概要 现代企业知识管理平台的演进呈现出全生命周期管理与智能服务网络构建的双重特征。通过四库体系(知识采集库、加工库、应用库、评估库)的协同运作,该系统实现了从知识沉淀、结构化处理到价值释放的完整闭环。其中,知识图…...
大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(3)
Paimon的下载及安装,并且了解了主键表的引擎以及changelog-producer的含义参考: 大数据组件(四)快速入门实时数据湖存储系统Apache Paimon(1) 利用Paimon表做lookup join,集成mysql cdc等参考: 大数据组件(四)快速入门实时数据…...
SVN把英文换中文
原文链接:SVN设置成中文版本 都是英文,换中文 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)添加用户名:admin,密码࿱…...
基于WebRTC与AI大模型接入EasyRTC:打造轻量级、高实时、强互动的嵌入式音视频解决方案
随着物联网和嵌入式技术的快速发展,嵌入式设备对实时音视频通信的需求日益增长。然而,传统的音视频解决方案往往存在体积庞大、实时性差、互动体验不佳等问题,难以满足嵌入式设备的资源限制和应用场景需求。 针对以上痛点,本文将介…...
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# 中,声明数组有多种方式,每种方式都有其适用的场景,下面为你逐一详细介绍: 1. 直接初始化声明 这种方式直观且便捷,在声明数组的同时就为其赋初值,让数组从诞生之初就拥有了具体的数据…...
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 结合动态加载组件
在实际项目中,有时候我们写好一个组件,但不是立即加载出来,而是触发某些条件后才动态的加载显示出来,当处理完某些操作后,再次将其关闭掉; 这样的需求,可以使用 Component 包裹着组件ÿ…...
Visual studio 2022 将打开文件的方式由单击改为双击
1. 打开vs2022,选择Tools -> Options打开Options设置页面 2. 在左侧依次展开Environment, 选择Tabs and Windows 3. 在右侧面板往下拖拽滚动条,找到Preview Tab section, unchecked "Preview selected files in Solution Explorer (Altclick t…...
网络工程师 (49)UDP协议
前言 UDP协议,即用户数据报协议(User Datagram Protocol),是一种无连接的、不可靠的、面向报文的传输层通信协议。 一、基本特点 无连接性:UDP在发送数据之前不需要与目标设备建立连接,也无需在数据发送结束…...
了解大数据
一、大数据的特点: 1.大量 2.高速 3.多样 结构化数据和非结构化数据 4.低价值密度 二、大数据的应用场景:视频推荐、电商推荐等 三、大数据的技术发展脉络 阶段1:单机时代 阶段2:大数据时代-分布式处理 阶段3:实…...
命令模式
1. 命令模式简介 命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,从而使您可以用不同的请求对客户进行参数化、对请求排队或记录请求日志,以及支持可撤销的操作。命令模式的核心思想是将操作和操作的执行者解耦,使得操作可以独立于执行者进…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
