左神高阶进阶班4 (尼姆博弈问题、k伪进制、递归到动态规划、优先级结合的递归套路、子串的递归套路,子序列的递归套路,动态规划的压缩技巧)

目录

【案例1  尼姆博弈问题】

【题目描述】

【思路解析】

【代码实现】

【案例2   k伪进制问题】

【题目描述】

【思路解析】

【代码实现】

【案例3   最大路径和】

【题目描述】

【思路解析】

【代码实现】

【案例4 优先级的递归套路】

【题目描述】

 【思路解析】

【代码实现】

【案例5  子串的递归套路 动态规划的空间压缩技巧】

【题目描述】

 【思路解析】

【代码实现】

【案例6 子序列的递归问题】

【问题描述】

 【思路解析】

【代码实现】


大家觉得写得可以的话,可以加入QQ群907575059.

【案例1  尼姆博弈问题】

【题目描述】

【思路解析】

异或和 指初始情况下,所有的铜板堆数量的异或和。

如果有1堆铜板,先手必赢,此时异或和不为0.

如果有2堆铜板,(1)两堆铜板数量相同,先手必输,此时异或和为0(2)两堆铜板数量不同,先手必胜,此时异或和不为0.

如果继续下去,我们可以发现我们最后怎么才能赢,就是拿过之后,必须保证异或和为0。当拿空时,异或和也为0。所以可以得出结论,当初始时异或和不为0,先手赢,但是如果硬币异或和不为0,后手赢。

【代码实现】

/*** @ProjectName: study3* @FileName: Ex1* @author:HWJ* @Data: 2023/9/23 16:46* 尼姆博弈问题*/
public class Ex1 {public static void main(String[] args) {}public static void getWin(int[] num){int xor = num[0];for (int i = 1; i < num.length; i++) {xor ^= num[i];}if (xor == 0){System.out.println("后手赢!");}else {System.out.println("先手赢!");}}
}

【案例2   k伪进制问题】

【题目描述】

【思路解析】

k伪进制和k进制的区别就在于它每个位置上必须有值,值的范围在 [1,k]之间,所以有个普遍想法就是先开始每个位置上尽量放1(从右至左),直到放不了了,然后从那个位置开始往右重新填数。

假如将103用7伪进制表示:1 1 1,只能填三个位置,剩下46,然后用这三个位置继续表示46即可。

【代码实现】

package AdvancedPromotion4;import java.util.HashMap;/*** @ProjectName: study3* @FileName: Ex2* @author:HWJ* @Data: 2023/9/23 16:56*/
public class Ex2 {public static void main(String[] args) {char[] chars = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};kConversion(123, chars);}public static void kConversion(int num, char[] chars) {int len = chars.length;HashMap<Integer, Integer> map = new HashMap<>();int max = 0;for (int i = 0; Math.pow(len, i) <= num; i++) {num -= (int) Math.pow(len, i);map.put(i, 1);max = i;}for (int i = max; i >= 0; i--) {int a = num / (int) Math.pow(len, i);num %= (int) Math.pow(len, i);map.put(i, map.get(i) + a);}StringBuilder str = new StringBuilder();for (int i = max; i >= 0; i--) {str.append(chars[map.get(i) - 1]);}System.out.println(str);}}

【案例3   最大路径和】

【题目描述】

【思路解析】

它不一定要达到最右边才会得到它的最长长度,即它可能在二维数组的任一位置得到最长长度。遍历数组每一个位置得到信息(包括没使用能力的最大长度,和使用能力的最大长度)。

但是每个位置又依靠它的左上位置,,左位置,左下位置,则需要使用递归。可以改为记忆化搜索和动态规划的版本。此题因为不存在枚举行为,所以记忆化搜索和动态规划的时间复杂度和空间复杂度相似。

【代码实现】

package AdvancedPromotion4;/*** @ProjectName: study3* @FileName: Ex3* @author:HWJ* @Data: 2023/9/23 20:12*/
public class Ex3 {public static void main(String[] args) {int[][] matrix = {{1, -4, 10}, {3, -2, -1}, {2, -1, 0}, {0, 5, -2}};System.out.println(getMaxLength1(matrix));}public static class Info {public int use;public int no;public Info(int no, int use) {this.use = use;this.no = no;}}// 递归版本public static int getMaxLength1(int[][] matrix) {int res = Integer.MIN_VALUE;for (int j = 0; j < matrix[0].length; j++) {for (int i = 0; i < matrix.length; i++) {Info cur = process1(matrix, i, j);int ans = Math.max(cur.no, cur.use);res = Math.max(ans, res);}}return res;}// 递归版本public static Info process1(int[][] matrix, int i, int j) {if (j == 0) {return new Info(matrix[i][j], -matrix[i][j]);}int preNo = -1;int preUse = -1;Info preLeft = process1(matrix, i, j - 1);if (preLeft.no >= 0) {preNo = preLeft.no;}if (preLeft.use >= 0) {preUse = preLeft.use;}if (i > 0) {Info preUp = process1(matrix, i - 1, j - 1);if (preUp.no >= 0) {preNo = Math.max(preUp.no, preNo);}if (preUp.use >= 0) {preUse = Math.max(preUse, preUp.use);}}if (i < matrix.length - 1) {Info preDown = process1(matrix, i + 1, j - 1);if (preDown.no >= 0) {preNo = Math.max(preDown.no, preNo);}if (preDown.use >= 0) {preUse = Math.max(preUse, preDown.use);}}int use = -1;int no = -1;if (preUse >= 0) {use = preUse + matrix[i][j];}if (preNo >= 0) {no = preNo + matrix[i][j];use = Math.max(use, preNo - matrix[i][j]);}return new Info(no, use);}// 记忆化搜索版本public static int getMaxLength2(int[][] matrix) {int res = Integer.MIN_VALUE;Info[][] map = new Info[matrix.length][matrix[0].length];for (int j = 0; j < matrix[0].length; j++) {for (int i = 0; i < matrix.length; i++) {Info cur = process2(matrix, i, j, map);int ans = Math.max(cur.no, cur.use);res = Math.max(ans, res);}}return res;}// 记忆化搜索版本版本public static Info process2(int[][] matrix, int i, int j, Info[][] map) {if (map[i][j] != null) { // 如果已经得到信息的地方,之间调用之前的信息return map[i][j];}if (j == 0) {map[i][j] = new Info(matrix[i][j], -matrix[i][j]);return map[i][j];}int preNo = -1;int preUse = -1;Info preLeft = process2(matrix, i, j - 1, map);if (preLeft.no >= 0) {preNo = preLeft.no;}if (preLeft.use >= 0) {preUse = preLeft.use;}if (i > 0) {Info preUp = process2(matrix, i - 1, j - 1, map);if (preUp.no >= 0) {preNo = Math.max(preUp.no, preNo);}if (preUp.use >= 0) {preUse = Math.max(preUse, preUp.use);}}if (i < matrix.length - 1) {Info preDown = process2(matrix, i + 1, j - 1, map);if (preDown.no >= 0) {preNo = Math.max(preDown.no, preNo);}if (preDown.use >= 0) {preUse = Math.max(preUse, preDown.use);}}int use = -1;int no = -1;if (preUse >= 0) {use = preUse + matrix[i][j];}if (preNo >= 0) {no = preNo + matrix[i][j];use = Math.max(use, preNo - matrix[i][j]);}map[i][j] = new Info(no, use);return map[i][j];}
}

【案例4 优先级的递归套路】

【题目描述】

 【思路解析】

先用栈实现不含括号的表达式求值,如果遇到运算符,且此时栈顶的运算符不为乘,除,就将运算符之前的数值和运算符加入栈,否则弹出运算符和运算符之前的数值,并且将其和当前数值进行运算后,在再将运算的值和当前运算符加入栈。

实现这个后我们考虑一个信息结构process(str,i)返回两个数值a,b  a表示从i开始到停止地方得到的运算结果,b表示它在哪里停止。遇到右括号或者到边界就停止。

【代码实现】

package AdvancedPromotion4;import java.util.LinkedList;/*** @ProjectName: study3* @FileName: Ex4* @author:HWJ* @Data: 2023/9/23 20:49*/
public class Ex4 {public static void main(String[] args) {String str = "48*((70-65)-43)+8*1";System.out.println(getNum(str));}public static int getNum(String str) {return process(str, 0)[0];}// 将每一个括号里面包含的运算式记作为一个整体进行计算。public static int[] process(String str, int index) {LinkedList<String> list = new LinkedList<>();int num = 0;while (index < str.length() && str.charAt(index) != ')') {if (str.charAt(index) >= '0' && str.charAt(index) <= '9') {num = num * 10 + str.charAt(index) - '0';index++;} else if (str.charAt(index) == '(') {  // 这里遇到左括号int[] ans = process(str, index + 1);index = ans[1] + 1; // 此次运算的结束位置num = ans[0]; // 括号里运算式总体的运算结果。} else { // 遇到运算符addNum(list, num);list.addLast(String.valueOf(str.charAt(index++)));num = 0;}}addNum(list, num);return new int[]{totalNum(list), index};}// 当栈顶运算符为乘或除时,暂时对运算式进行计算。public static void addNum(LinkedList<String> list, int num) {if (!list.isEmpty()) {int cur = 0;String operator = list.pollLast();if (operator.equals("+") || operator.equals("-")) {list.addLast(operator);} else {cur = Integer.valueOf(list.pollLast());num = operator.equals("*") ? num * cur : cur / num;}}list.addLast(String.valueOf(num));}// 处理完后整个栈里只剩下数值和加减运算符public static int totalNum(LinkedList<String> list) {int res = 0;boolean add = true;String cur = null;int num = 0;while (!list.isEmpty()) {cur = list.pollFirst();if (cur.equals("+")) {add = true;}else if(cur.equals("-")){add = false;}else {num = Integer.valueOf(cur);res += add ? num : (-num);}}return res;}
}

【案例5  子串的递归套路 动态规划的空间压缩技巧】

【题目描述】

 【思路解析】

因为子串一定是在字符串中连续的字符子串。两个字符串的最长公共子串可能以str1的任意位置结尾和str2的任意位置结尾,但是因为是公共子串则要求两个的对应位置字符相同,所以如果str1以i结尾和str2以j结尾的公共子串长度取决于str1以i - 1结尾和str2以j - 1结尾的公共子串长度 + 1.(str1以i结尾和str2以j结尾的字符相同)

根据标红的对应关系可知,dp[i][j]只依赖与dp[i-1][j-1],所以我们可以不必要创建一个二维数组来进行dp。例如如下规则来对动态规划空间进行压缩。

107421
1311853
15141296

以上数字代表优化后的填表技巧,当填3时,我们只记录2,填4时只记录3.将整个表优化为一个变量。

【代码实现】

package AdvancedPromotion4;/*** @ProjectName: study3* @FileName: Ex5* @author:HWJ* @Data: 2023/9/23 21:27*/
public class Ex5 {public static void main(String[] args) {String str1 = "kaaabcFght";String str2 = "ksaaabmFght";System.out.println(getSameLen1(str1, str2));System.out.println(getSameLen2(str1, str2));}public static int getSameLen1(String s1, String s2){int[][] dp = new int[s1.length()][s2.length()];char[] str1 = s1.toCharArray();char[] str2 = s2.toCharArray();int res = 0;for (int i = 0; i < str1.length; i++) {for (int j = 0; j < str2.length; j++) {if (i == 0 || j == 0){if (str1[i] == str2[j]){dp[i][j] = 1;res = Math.max(dp[i][j], res);}}else {if (str1[i] == str2[j]){dp[i][j] = dp[i - 1][j - 1] + 1;res = Math.max(dp[i][j], res);}}}}return res;}public static String  getSameLen2(String s1, String s2){int len = 0;char[] str1 = s1.toCharArray();char[] str2 = s2.toCharArray();int max = 0;int end = 0;int row = 0;int col = s2.length() - 1;while (row < s1.length()){len = 0;int i = row;int j = col;while (i < s1.length() && j < s2.length()){if (str1[i] == str2[j]){len++;if (len > max){max = len;end = i;}}else {len = 0;}i++;j++;}if (col > 0){col--;}else {row++;}}return s1.substring(end - max + 1, end + 1);}
}

【案例6 子序列的递归问题】

【问题描述】

 【思路解析】

因为子串一定是在字符串中满足原顺序的字符序列,可以不连续。

所以对任意dp[i][j]表示以i位置结尾的str1,表示以j位置结尾的str2的两个子串上最长公共子序列的长度。

对于这个最长公共子序列有4种可能性:

(1)最长公共子序列包含i位置,包含j位置。

(2)最长公共子序列不包含i位置,包含j位置。

(3)最长公共子序列包含i位置,不包含j位置。

(4)最长公共子序列不包含i位置,不包含j位置。

【代码实现】

package AdvancedPromotion4;/*** @ProjectName: study3* @FileName: Ex6* @author:HWJ* @Data: 2023/9/23 22:04*/
public class Ex6 {public static void main(String[] args) {String str1 = "kaaabcFght";String str2 = "ksaaabmFght";System.out.println(getSameLen(str1, str2));}public static int getSameLen(String s1, String s2){int[][] dp = new int[s1.length()][s2.length()];char[] str1 = s1.toCharArray();char[] str2 = s2.toCharArray();int res = 0;for (int i = 0; i < str1.length; i++) {for (int j = 0; j < str2.length; j++) {if (i == 0 && j == 0){if (str1[i] == str2[j]){dp[i][j] = 1;res = dp[i][j];}}else {if (i == 0){dp[i][j] = dp[i][j - 1];res = Math.max(dp[i][j], res);}else if(j == 0){dp[i][j] = dp[i - 1][j];res = Math.max(dp[i][j], res);}else {int p1 = dp[i][j - 1];int p2 = dp[i - 1][j];int p3 = dp[i - 1][j - 1] + (str1[i] == str2[j] ? 1 : 0);dp[i][j] = Math.max(p1, Math.max(p2, p3));res = Math.max(dp[i][j], res);}}}}return res;}
}

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

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

相关文章

Android 遍历界面所有的View

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、实践四、 推荐阅读 一、导读 我们…

Python Opencv实践 - 视频目标追踪MeanShift

参考资料&#xff1a; opencv/python标定时用到的几个函数意义_criteria opencv_是三水不是泗水的博客-CSDN博客 pythonOpenCV笔记&#xff08;二十六&#xff09;&#xff1a;视频追踪&#xff08;meanshift、Camshift&#xff09;_cv2.meanshift_ReadyGo!!!的博客-CSDN博客…

获取文件最后修改时间

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Java源码 public void testGetFileTime() {try {String string "E://test.txt";File file new File(string);Path path file.toPath();BasicFileAttributes ba…

树结构构建,字典树快速生成。

表结构 查出list后&#xff0c;用工具类转换。工具类代码如下&#xff1a; 下面展示一些 内联代码片。 public static List<JSONObject> toTreeList(List tList, String oidkey, Stripspidkey) List<JSONObject> jsonObjectList JSONArray. parseArray (JSON.…

Leetcode—— 20.有效的括号

20. 有效的括号 给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭…

Idea中使用Service管理微服务

前言 如何在本地一键启动很多个微服务&#xff0c;下面介绍下IDEA开发工具中得Services管理管理功能 一、第一步 1、在IDEA中下栏bar中如果存在Services,请看第二步。 2、如果没有请按照以下步骤打开 View -> Tool Windows -> Services 二、第二步 刚创建好的窗口是空…

千呼万唤openGauss资源池化系列培训来了

应openGauss广大用户要求&#xff0c;社区于近期推出openGauss资源池化培训系列。 关于资源池化 资源池化是openGauss 5.0.0 推出的重点特性&#xff0c;是openGauss基于内存池化和共享存储实现的数据库集群。数据在集群的计算节点内存、共享存储中实现共享。应用可以任意节点…

DLT645-2007智能电表通讯规约 协议读取数据实战

【本文发布于https://blog.csdn.net/Stack_/article/details/132946097&#xff0c;未经许可不得转载&#xff0c;转载须注明出处】 协议文档&#xff1a;DL-T 645-2007 多功能电能表通信协议 先用电表厂家提供的上位机进行通讯并拦截数据&#xff0c;再对照协议文档进行以下分…

Centos7完全离线环境安装Nvidia Tesla A100 40G显卡驱动(含CUDA Toolkit)和Anaconda3虚拟环境

公司一台完全离线环境的服务器刚装了Nvidia Tesla A100 40G显卡&#xff0c;自己摸索着将显卡驱动在完全离线环境下安装成功&#xff0c;这里记录一下。 一、下载Centos7适配的Nvidia Tesla A100 40G显卡驱动 在Nvidia官网下载Centos7适配的显卡驱动&#xff0c;CUDA Toolkit…

mybatis-plus异常:dynamic-datasource can not find primary datasource

现象 使用mybatis-plus多数据源配置时出现异常 com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException: dynamic-datasource can not find primary datasource分析 异常原因是没有设置默认数据源&#xff0c;在类上没有使用DS指定数据源时&#xff0c;默…

【WSL】仅适用于装C盘情况-用WSL在win10安装LInux

研究了一点点伪分布式的内容。决定搞一个Linux系统玩一下 参考来自微软官方安装步骤&#xff1a; 旧版 WSL 的手动安装步骤 https://learn.microsoft.com/zh-cn/windows/wsl/install-manual WSL全称为&#xff0c;Windows Subsystem for Linux 法一&#xff1a;应用商店装 查…

pytest框架前后置设置,以及pytest默认规则

一、pytest框架的默认规则 1、模块名默认必须以test开头或者以test结尾 2、测试类必须以Test开头&#xff0c;并且不能有__init__方法 3、测试方法默认必须以test开头 当然以后的一些默认规则除测试类不能使用__init__方法外其余的都是可配置的&#xff0c;当然一般情况下我们…