动态规划(Java)

article/2025/9/11 18:30:57

文章目录

  • 前言
  • 一、背包问题
  • 二、字符串转化问题
  • 三、纸牌问题
  • 四、最少贴纸数
  • 总结


前言

动态规划的目的就是避免重复计算,在暴力递归的过程中若在计算过程中产生了重复计算那么就可以进行动态规划的优化。以空间换时间,可以根据暴力递归的过程写出动态规划的过程。


一、背包问题

题目:
在这里插入图片描述

public class BagProblem {public static int solution(int[] weights, int[] values, int bag) {int[][] dp = new int[weights.length + 1][bag + 1];for(int i=weights.length - 1; i>=0; --i) {for(int j=1; j<=bag; ++j) {dp[i][j] = dp[i + 1][j];if(j >= weights[i]) {dp[i][j] = Math.max(dp[i][j], values[i] + dp[i+1][j-weights[i]]);}}}return dp[0][bag];}public static void main(String[] args) {System.out.println(solution(new int[] {20, 30, 100}, new int[] {40, 50, 80}, 100));}}

运行结果:
在这里插入图片描述

二、字符串转化问题

题目:
在这里插入图片描述

package DynamicProgramming;public class TransString {public static int solution(String str) {int len = str.length();int[] dp = new int[len + 1];dp[len] = 1;for(int i=len-1; i>=0; --i) {if(str.charAt(i) == '0') {dp[i] = 0;}else if(str.charAt(i) == '1') {dp[i] = dp[i + 1];if(i != len - 1) {dp[i] += dp[i + 2];}}else if(str.charAt(i) == '2') {dp[i] = dp[i + 1];if(i != len - 1 && str.charAt(i) >= '0' && str.charAt(i) <= '6') {dp[i] += dp[i + 2];}}else {dp[i] = dp[i + 1];}}return dp[0];}public static void main(String[] args) {System.out.println(solution("1111"));}}

运行结果
在这里插入图片描述

三、纸牌问题

题目:
在这里插入图片描述

package DynamicProgramming;import java.util.Arrays;public class PaperCardScore {public static String solution(int[] card) {int n = card.length;int[][] first = new int[n][n];	//先手矩阵int[][] second = new int[n][n];	//后手矩阵for(int i=0; i<n; i++) {first[i][i] = card[i];	//只剩下一张牌,先手会取走这张 后手为0}//r为剩余牌的数量for(int r=2; r<=n; r++) {// 枚举范围for(int i=0;i<n - r + 1;++i) {int j = i + r - 1;first[i][j] = Math.max(card[i] + second[i+1][j], card[j] + second[i][j - 1]);	// 取左边牌和右边牌 看那边大second[i][j] = Math.min(first[i + 1][j], first[i][j - 1]);						// 假如先手取左边 假如先手取右边 后手被动只能要小的}}String ret = "先手分数为:" + first[0][n - 1] + " 后手分数为:" + second[0][n - 1];if(first[0][n - 1] > second[0][n - 1]) {ret = "先手胜利! " + ret;}else if(first[0][n - 1] < second[0][n - 1]) {ret = "后手胜利! " + ret;}else {ret = "平局! " + ret;}return ret;}public static void main(String[] args) {int[][] cards = new int[][] {{1, 100, 20, 30 , 2},{1, 300, 2},{1, 300, 500},{300, 300},{20, 25, 85, 42, 8},{1, 2, 3, 4 ,5, 42}};for(int i=0; i<cards.length; ++i) {System.out.println("---------" + Arrays.toString(cards[i]) + "---------");System.out.println(solution(cards[i]));System.out.println();}}
}

运行结果
在这里插入图片描述

四、最少贴纸数

题目
在这里插入图片描述
思路: 记忆化搜索

package DynamicProgramming;import java.util.HashMap;public class lestStickNum {public static int solution(String str, String[] stick) {int m = stick.length;int[][] map = new int[m][26];	// 构造贴纸mapfor(int i=0; i<m; ++i) {int len = stick[i].length();for(int j=0; j<len; ++j) {map[i][stick[i].charAt(j) - 'a'] += 1;}}HashMap<String, Integer> dp = new HashMap<>();	// 存储记忆dp.put("", 0);					// 空字符串用0张return helper(map, str, dp);}public static int helper(int[][] map, String rest, HashMap<String, Integer> dp) {if(dp.containsKey(rest)) {return dp.get(rest);}int len = rest.length();int[] temp = new int[26];for(int i=0; i<len; ++i) {temp[rest.charAt(i) - 'a']++;}int ans = Integer.MAX_VALUE;for(int i=0; i<map.length; ++i) {if(map[i][rest.charAt(0) - 'a'] == 0) {	// 必须有字符匹配,这里匹配第一个continue;}int[] newRest = new int[26];StringBuilder sb = new StringBuilder();for(int j=0; j<26; ++j) {newRest[j] = temp[j] - map[i][j] >= 0? temp[j] - map[i][j] :0;for(int k=0; k<newRest[j]; k++) {sb.append((char)('a' + j));}}int next = helper(map, sb.toString(), dp);		// 匹配剩余字符串最少几张贴纸if(next != -1) {ans = ans > next + 1? next + 1: ans;}}if(ans == Integer.MAX_VALUE) ans = -1;	// -1表示无法匹配dp.put(rest, ans);return ans;}public static void main(String[] args) {System.out.println(solution("aabbccdd", new String[] {"a", "b", "c", "d"}));System.out.println(solution("aabbccdd", new String[] {"ab", "b", "c", "d"}));System.out.println(solution("aabbccdd", new String[] {"abc", "b", "c", "d"}));System.out.println(solution("aabbccdd", new String[] {"abdc", "b", "c", "d"}));System.out.println(solution("aabbccdd", new String[] {"abc", "b", "c"}));}
}

运行结果:
在这里插入图片描述


总结

步骤: 题 -> 找到暴力递归算法 -> 有重复解 -> 找打可变参数 -> 记忆化搜索 -> 精细化组织变为经典的动态规划算法

什么暴力递归可以继续优化?
有重复调用同一个子问题的解,这种递归可以优化,如果每一个子问题都是不同的解,无法优化也不用优化

面试中设计暴力递归过程的原则

  1. 每一个可变参数的类型、一定不要比int类型更加复杂
  2. 原则一可以违反,让类型突破到一位线性结构,那必须是唯一可变参数
  3. 如果原则一被违反,但不违反原则二,只需要记忆化搜索即可
  4. 可变参数的个数,能少则少

http://chatgpt.dhexx.cn/article/Dbgfp68x.shtml

相关文章

袋鼠云与中航金网达成战略合作,成立信创大数据联合实验室

当前&#xff0c;加快推进“新基建”已成为新形势下国家稳定经济发展的重要方针&#xff0c;而作为“新基建底座”的信创产业&#xff0c;有望成为未来中国十年科技发展的核心领域。纵观信创产业近五年发展&#xff0c;产品和技术已从“基本可用”向“好用易用”大跨步迈进&…

北京市委书记蔡奇调研 PingCAP 立足自主研发和开源战略,助推产业数字化转型

2021 年 3 月&#xff0c;开源正式被列入国家十四五规划发展纲要&#xff0c;可以预期&#xff0c;开源将成为中国未来发展基础软硬件技术的关键路径。**3 月 23 日上午&#xff0c;北京市委书记蔡奇一行参观考察 PingCAP&#xff08;平凯星辰&#xff09;&#xff0c;专题调研…

如何把pdf转成图片?

怎么把pdf转成图片&#xff1f;作为上班族&#xff0c;能熟练的使用各种办公软件是职场必备技能&#xff0c;特别是在处理各种类型的文件时候&#xff0c;如果能熟练的将文件格式进行相互转换&#xff0c;那不仅能提升自己的工作效率&#xff0c;也会方便跟自己对接工作的人。就…

袋鼠云与沃趣科技达成战略合作,共同驱动企业数字化升级

12月3日,袋鼠云与沃趣科技正式达成战略合作,并于袋鼠云总部举行签约仪式。沃趣科技创始人&CEO 陈栋、联合创始人&CTO 李建辉、合伙人&总裁 郭华、技术中心负责人 魏兴华,袋鼠云创始人&董事长 陈吉平、联合创始人&CEO 徐进挺、联合创始人&易知微CEO 宁海…

袋鼠云陈吉平:深耕国产自研数字化技术与服务,持续为客户创造价值

在经济面临下行压力、疫情反复等不确定因素之下&#xff0c;推动数字化转型就成为了许多企业的“救命稻草”。然而&#xff0c;较高的数字化转型门槛、不成系统的数据服务&#xff0c;以及缺乏规范的行业标准等都成了企业数字化转型路上的“绊脚石”。 ​ 2015年&#xff0c;…

陈吉平-阿里巴巴离职DBA在35岁总结的职业生涯

导读&#xff1a;去年很多朋友私下或新浪微博上在总结自己的职业生涯与职业规划&#xff0c;也感觉到很纠结与彷徨&#xff0c;尤其技术人的职业生涯&#xff0c;随年龄增加&#xff0c;一些优势逐渐丧失。4月 13 日数据库技术大会的主办方举行的晚宴上&#xff0c;也让本人支持…

从产品到平台和生态,数据中台「竞争」升级

据可靠信源&#xff0c;中国首家数据中台公司袋鼠云已于去年年底完成C轮融资&#xff0c;由中信证券领投&#xff0c;东方富海、杭州凯泰资本跟投。 这意味着自去年以来颇受争议的数据中台赛道已经有公司率先突破C轮魔咒、迈上新台阶。 创投圈存在一个“C轮死”的魔咒&#xff…

B12专访 | 袋鼠云拖雷:未来十年是数据中台的黄金年代

B座12楼(以下简称“B12”&#xff09;&#xff0c;关注创业和投资的互联网媒体&#xff0c;精准覆盖创投圈数十万粉丝&#xff0c;让创新得到赞赏。 最近&#xff0c;B12找到拖雷&#xff0c;聊了聊大众对数据中台的认知误区、袋鼠云的数据中台“51”方法论以及袋鼠云的生态等&…

陈吉平的Oracle职业生涯:兴趣与思考 成败之所系

陈吉平的Oracle职业生涯&#xff1a;兴趣与思考 成败之所系 出处信息 编者按&#xff1a;这是陈吉平以前在ITPUB论坛上写下的职业生涯总结&#xff0c;随着时间推移&#xff0c;他早已经从技术岗位转向了管理&#xff0c;现在带领团队承担着淘宝无线的开发工作(现在淘宝拆分了&…

空间任一点到超平面的距离公式的推导过程

在感知机模型中&#xff0c;输入空间中任意一点 到超平面S的距离&#xff1a; 其推导过程如下&#xff1a;

点到平面的距离计算

在工程计算过程中&#xff0c;往往要求我们计算点到平面的距离&#xff0c;特别是在计算机图形学中的运用最多。如图1所示&#xff0c;已知一个平面Plan的方向n和该平面上的顶点B&#xff0c;求空间中某一个顶点P到该平面的距离。假设点P在平面Plan上的投影点为P1&#xff0c;那…

史上最全的点线面距离公式与推导过程(图文介绍)

目录 点到点的距离 点到直线的距离 点到面的距离 直线与直线间的距离 直线与面的距离 面与面之间的距离 选证 点到空间直线的距离 点到平面的距离 异面直线之间的距离 点到点的距离 点到直线的距离 点到面的距离 直线与直线间的距离 直线与面的距离 面与面之间的距离…

三点求平面方程、平面法向量和点到平面的距离

已知三点p1&#xff08;x1,y1,z1&#xff09;&#xff0c;p2(x2,y2,z2)&#xff0c;p3(x3,y3,z3)&#xff0c; 要求确定的平面方程,关键在于求出平面的一个法向量 为此做向量p1p2&#xff08;x2-x1,y2-y1,z2-z1), p1p3(x3-x1,y3-y1,z3-z1),平面法线和这两个向量垂直&#xff…

数学基础二:点到直线距离公式推导

推导前置&#xff1a;两点之间距离公式 图一&#xff1a; 已知AB两点坐标为A&#xff08;x1,y1&#xff09;&#xff0c;B(x2,y2)。 过A做一直线与X轴平行&#xff0c;过B做一直线与Y轴平行&#xff0c;两直线交点为C。 则AC垂直于BC&#xff08;因为X轴垂直于Y轴&#xff09…

SVM:任意点到超平面的距离公式

任意点 到超平面的距离公式 在样本空间中&#xff0c;划分超平面可通过如下线性方程来描述: 其中 w 决定了超平面的方向 ; b 为位移项&#xff0c;决定了超平面与原点之间的距离.显然&#xff0c;划分超平面可被法向量 ω 和位移 b 确定 。 任意点到超平面的距离公式为&…

平面方程、两平面的夹角、空间点到平面的距离公式

空间直线方程及两直线的夹角 1.空间直线的一般方程 方向向量 与一直直线平行的非零向量 求法参照2.对称式方程 2.空间直线的点向式&#xff08;对称式&#xff09;方程 求的是平面 特殊情况 3.空间直线的参数方程&#xff08;引入参数t&#xff09; 两直线的夹角&#x…

点到直线的距离公式推导

点到直线的距离公式推导 本文地址&#xff1a;blog.lucien.ink/archives/495 摘自 点到直线距离公式的几种推导 - 三横先生的文章 - 知乎 的三角形面积法&#xff0c;稍作修改并更正书写错误。 起因 今天在 PPT 里看到一个点到超平面的距离公式 d 1 ∥ w ∥ ∣ w ⋅ x 0 b…

点到平面的距离公式的推导

点到平面的距离公式 准备知识 平面的一般式方程 Ax By Cz D 0 其中n (A, B, C)是平面的法向量&#xff0c;D是将平面平移到坐标原点所需距离&#xff08;所以D0时&#xff0c;平面过原点&#xff09; 向量的模&#xff08;长度&#xff09; 给定一个向量V&#xff08;…

点到平面的基本距离推导公式

这是高中时候的基础数学&#xff0c;然而也是比较重要的一个知识点&#xff0c;在很多地方都会用到&#xff0c;在基于超平面分类算法中&#xff0c;向量空间中任意一点到超平面的距离也是一个基础知识点 平面的一般式方程 Ax By Cz D 0 其中n (A, B, C)是平面的法向量&am…