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

算法体系-21 第二十一 暴力递归到动态规划(三)

一 最长回文子串

1.1 描述

给定一个字符串str,返回这个字符串的最长回文子序列长度

比如 : str = “a12b3c43def2ghi1kpm”

最长回文子序列是“1234321”或者“123c321”,返回长度7

1.2 分析

1.2.1 先将原传逆序,求原串和反转后的串的最长公共子序列就是原串的最长回文子序列

1.2 分析

1.2.1 先将原传逆序,求原串和反转后的串的最长公共子序列就是原串的最长回文子序列

1.3 反转求最长公共子序列 代码

    public static int longestPalindromeSubseq1(String s) {if (s == null || s.length() == 0) {return 0;}if (s.length() == 1) {return 1;}char[] str = s.toCharArray();char[] reverse = reverse(str);return longestCommonSubsequence(str, reverse);}public static int longestCommonSubsequence(char[] str1, char[] str2) {int N = str1.length;int M = str2.length;int[][] dp = new int[N][M];dp[0][0] = str1[0] == str2[0] ? 1 : 0;for (int i = 1; i < N; i++) {dp[i][0] = str1[i] == str2[0] ? 1 : dp[i - 1][0];}for (int j = 1; j < M; j++) {dp[0][j] = str1[0] == str2[j] ? 1 : dp[0][j - 1];}for (int i = 1; i < N; i++) {for (int j = 1; j < M; j++) {dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);if (str1[i] == str2[j]) {dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + 1);}}}return dp[N - 1][M - 1];}

1.3.1 分析二 上节用的是样本对应模型,这里用别的做法 (范围尝试模型 这种模型特别在乎讨论开头如何如何 结尾如何如何)

样本对应模型(特别在乎两个样本结尾如何如何) 范围尝试模型往开头如何如何,结尾如何如何

范围讨论如下-递归含义的定义如下

1.3.2 分析 有以下四种情况

1)不以L开头,不以R结尾

2)以L开头,不以R结尾

3)不以L开头,以R结尾

4)以L开头,以R结尾

1.4 尝试递归代码

    public static int lpsl1(String s) {if (s == null || s.length() == 0) {return 0;}char[] str = s.toCharArray();return f(str, 0, str.length - 1);}// str[L..R]最长回文子序列长度返回public static int f(char[] str, int L, int R) {if (L == R) {return 1;}if (L == R - 1) {return str[L] == str[R] ? 2 : 1;}int p1 = f(str, L + 1, R - 1);int p2 = f(str, L, R - 1);int p3 = f(str, L + 1, R);int p4 = str[L] != str[R] ? 0 : (2 + f(str, L + 1, R - 1));return Math.max(Math.max(p1, p2), Math.max(p3, p4));}

1.5 改动态规划分析

除了if (L == R) {

return 1;}

if (L == R - 1) {

return str[L] == str[R] ? 2 : 1;}

这两位置之后,其他位置的填的方法 从底往上填 每一行从左往右er

//跟进下面得图形推导出所求剩下得范围

for (int i = N - 3; i >= 0; i--)

for (int j = i + 2; j < N; j++)

1.6改动太规划代码

    public static int longestPalindromeSubseq2(String s) {if (s == null || s.length() == 0) {return 0;}if (s.length() == 1) {return 1;}char[] str = s.toCharArray();int N = str.length;int[][] dp = new int[N][N];dp[N - 1][N - 1] = 1;for (int i = 0; i < N - 1; i++) {dp[i][i] = 1;dp[i][i + 1] = str[i] == str[i + 1] ? 2 : 1;}//跟进上面得图形推导出所求剩下得范围for (int i = N - 3; i >= 0; i--) {for (int j = i + 2; j < N; j++) {dp[i][j] = Math.max(dp[i][j - 1], dp[i + 1][j]);if (str[i] == str[j]) {dp[i][j] = Math.max(dp[i][j], dp[i + 1][j - 1] + 2);}}}return dp[0][N - 1];}}

二 返回象棋从一个位置到另一个位置的方法有多少种

2.1 描述

请同学们自行搜索或者想象一个象棋的棋盘,

然后把整个棋盘放入第一象限,棋盘的最左下角是(0,0)位置

那么整个棋盘就是横坐标上9条线、纵坐标上10条线的区域

给你三个 参数 x,y,k

返回“马”从(0,0)位置出发,必须走k步

最后落在(x,y)上的方法数有多少种?

象棋走的日

2.2 分析 样本对应模型

跳的所有8方法

2.3 递归代码

// 当前来到的位置是(x,y)// 还剩下rest步需要跳// 跳完rest步,正好跳到a,b的方法数是多少?// 10 * 9public static int jump(int a, int b, int k) {return process(0, 0, k, a, b);}public static int process(int x, int y, int rest, int a, int b) {if (x < 0 || x > 9 || y < 0 || y > 8) {return 0;}if (rest == 0) {return (x == a && y == b) ? 1 : 0;}int ways = process(x + 2, y + 1, rest - 1, a, b);ways += process(x + 1, y + 2, rest - 1, a, b);ways += process(x - 1, y + 2, rest - 1, a, b);ways += process(x - 2, y + 1, rest - 1, a, b);ways += process(x - 2, y - 1, rest - 1, a, b);ways += process(x - 1, y - 2, rest - 1, a, b);ways += process(x + 1, y - 2, rest - 1, a, b);ways += process(x + 2, y - 1, rest - 1, a, b);return ways;}

2.4 改动态规划

是个三维数组,要的是rest的数据,rest要的数据是rest-1的数据 最终rest==0又是知道的

    public static int dp(int a, int b, int k) {int[][][] dp = new int[10][9][k + 1];dp[a][b][0] = 1;for (int rest = 1; rest <= k; rest++) {for (int x = 0; x < 10; x++) {for (int y = 0; y < 9; y++) {int ways = pick(dp, x + 2, y + 1, rest - 1);ways += pick(dp, x + 1, y + 2, rest - 1);ways += pick(dp, x - 1, y + 2, rest - 1);ways += pick(dp, x - 2, y + 1, rest - 1);ways += pick(dp, x - 2, y - 1, rest - 1);ways += pick(dp, x - 1, y - 2, rest - 1);ways += pick(dp, x + 1, y - 2, rest - 1);ways += pick(dp, x + 2, y - 1, rest - 1);dp[x][y][rest] = ways;}}}return dp[0][0][k];}public static int pick(int[][][] dp, int x, int y, int rest) {if (x < 0 || x > 9 || y < 0 || y > 8) {return 0;}return dp[x][y][rest];}

相关文章:

  • 专业学习|博弈论-博弈论概述
  • .NET MAUI Sqlite数据库操作(二)异步初始化方法
  • Mysql的增、删、查、改
  • 使用python绘制三维散点图
  • RK平台Android单独编译内核
  • 【打鼹鼠game】
  • 深度学习Day-20:DenseNet算法实战 乳腺癌识别
  • mysql在linux下安装与配置
  • AI 定位!GeoSpyAI上传一张图片分析具体位置 不可思议! ! !
  • 做外贸开发客户使用外贸软件有必要吗?
  • Ionic 创建 APP
  • 【Ubuntu20.04】安装XRDP远程桌面服务
  • scrapy爬取豆瓣书单存入MongoDB数据库
  • 算法:位运算题目练习
  • 图像分隔和深度成像技术为什么受市场欢迎-数字孪生技术和物联网智能汽车技术的大爆发?分析一下图像技术的前生后世
  • 【附node操作实例】redis简明入门系列—字符串类型
  • css的样式优先级
  • css选择器
  • HTTP--网络协议分层,http历史(二)
  • javascript从右向左截取指定位数字符的3种方法
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Rancher如何对接Ceph-RBD块存储
  • Vue 2.3、2.4 知识点小结
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 浅谈web中前端模板引擎的使用
  • 如何实现 font-size 的响应式
  • 无服务器化是企业 IT 架构的未来吗?
  • 一天一个设计模式之JS实现——适配器模式
  • 译有关态射的一切
  • 用Visual Studio开发以太坊智能合约
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 交换综合实验一
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • #14vue3生成表单并跳转到外部地址的方式
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (利用IDEA+Maven)定制属于自己的jar包
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .gitattributes 文件
  • .NET Micro Framework 4.2 beta 源码探析
  • .NET Micro Framework初体验(二)
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端
  • .NET 材料检测系统崩溃分析
  • .NET 快速重构概要1
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .NET程序员迈向卓越的必由之路
  • .Net环境下的缓存技术介绍
  • .net中我喜欢的两种验证码
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?