算法|10.从暴力递归到动态规划3

news2024/12/23 9:41:34

算法|10.从暴力递归到动态规划3

1.纸牌游戏

题意:给定一个整型数组arr(都是正数),代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿。但是每个玩家每次只能拿走最左或最右的纸牌。玩家A和玩家B都绝顶聪明,请返回最后获胜者的分数。

解题思路:

  • “绝顶聪明”,意味着他们会尽可能保证自己拿的分数高,同时对手得到的分数低。
  • 这里分成了先手姿态和后手姿态

核心代码:

递归代码:

public static int win1(int[] arr) {
    if(arr==null||arr.length==0){
        return 0;
    }
    int first=f1(arr,0, arr.length-1);
    int second=g1(arr,0,arr.length-1);
    return Math.max(first,second);
}

public static int f1(int[] arr, int L, int R) {
     if(L==R){
         return arr[L];
     }
     int p1=arr[L]+g1(arr,L+1,R);
     int p2=arr[R]+g1(arr,L,R-1);
     return Math.max(p1,p2);
}

public static int g1(int[] arr, int L, int R) {
     if(L==R){
         return 0;
     }
     int p1=f1(arr,L+1,R);
     int p2=f1(arr,L,R-1);
     return Math.min(p1,p2);
}

缓存的方法:

public static int win2(int[] arr) {
    if (arr == null || arr.length == 0) {
        return 0;
    }
    int N = arr.length;
    int[][] fmap = new int[N][N];
    int[][] gmap = new int[N][N];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            fmap[i][j] = -1;
            gmap[i][j] = -1;
        }
    }
    int first = f2(arr, 0, arr.length - 1, fmap, gmap);
    int second = g2(arr, 0, arr.length - 1, fmap, gmap);
    return Math.max(first, second);
}

// arr[L..R],先手获得的最好分数返回
public static int f2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {
    if (fmap[L][R] != -1) {
        return fmap[L][R];
    }
    int ans = 0;
    if (L == R) {
        ans = arr[L];
    } else {
        int p1 = arr[L] + g2(arr, L + 1, R, fmap, gmap);
        int p2 = arr[R] + g2(arr, L, R - 1, fmap, gmap);
        ans = Math.max(p1, p2);
    }
    fmap[L][R] = ans;
    return ans;
}

// // arr[L..R],后手获得的最好分数返回
public static int g2(int[] arr, int L, int R, int[][] fmap, int[][] gmap) {
    if (gmap[L][R] != -1) {
        return gmap[L][R];
    }
    int ans = 0;
    if (L != R) {
        int p1 = f2(arr, L + 1, R, fmap, gmap); // 对手拿走了L位置的数
        int p2 = f2(arr, L, R - 1, fmap, gmap); // 对手拿走了R位置的数
        ans = Math.min(p1, p2);
    }
    gmap[L][R] = ans;
    return ans;
}

dp代码:

public static int win3(int[] arr) {
    int N = arr.length;
    int[][] fmap = new int[N][N];
    int[][] gmap = new int[N][N];
    for (int i = 0; i < N; i++) {
        fmap[i][i] = arr[i];
    }
    for (int startCol = 1; startCol < N; startCol++) {
        int L = 0;
        int R = startCol;
        while (R < N) {
            fmap[L][R] = Math.max(arr[L] + gmap[L + 1][R], arr[R] + gmap[L][R - 1]);
            gmap[L][R] = Math.min(fmap[L + 1][R], fmap[L][R - 1]);
            L++;
            R++;
        }
    }
    return Math.max(fmap[0][N - 1], gmap[0][N - 1]);
}

测试代码:

public static void main(String[] args) {
    int[] arr = { 5, 7, 4, 5, 8, 1, 6, 9,10,3, 4,100, 6, 1, 7 };
    System.out.println(win1(arr));
    System.out.println(win2(arr));
    System.out.println(win3(arr));

}

测试结果:在这里插入图片描述

2.最长回文子串

题意:给定一个字符串str,返回这个字符串的最长回文子序列长度
比如 : str = “a12b3c43def2ghi1kpm”,最长回文子序列是“1234321”或者“123c321”,返回长度7。

解题思路:

  • 剩余的个数为1,返回1
  • 剩余的个数为2,返回2
  • 否则分都要,要左边,要右边,两边都要四种情况,最终取最大值
  • 以上分类均给予坐标LR之间的关系

核心代码:

递归代码:

public static int lps(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 (R - L == 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));
}

dp代码:

public static int dp(String s) {
    if (s == null || s.length() == 0) {
        return 0;
    }
    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 L = N - 3; L >= 0; L--) {
        for (int R = L + 2; R < N; R++) {
            dp[L][R] = Math.max(dp[L][R - 1], dp[L + 1][R]);
            if (str[L] == str[R]) {
                dp[L][R] = Math.max(dp[L][R], 2 + dp[L + 1][R - 1]);
            }
        }
    }
    return dp[0][N - 1];
}

测试:测试链接

区间范围尝试模型总结

改写dp:

例题总结:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(10) 朴素贝叶斯

文章目录 1 概述2 不同分布下的贝叶斯2.1 高斯朴素贝叶斯GaussianNB2.1.1 认识高斯朴素贝叶斯2.1.2 探索贝叶斯&#xff1a;高斯朴素贝叶斯擅长的数据集2.1.3 探索贝叶斯&#xff1a;高斯朴素贝叶斯的拟合效果与运算速度 2.2 概率类模型的评估指标2.2.1 布里尔分数Brier Score2…

PCIE知识点-022:PCIe 时钟结构

图1&#xff1a;参考时钟结构示意图[4] 1. Common Refclk Architecture Common Refclk Architecture&#xff0c;即同源参考时钟架构&#xff0c;PCIe收发设备共用一个时钟源&#xff0c;是目前是使用最为广泛的方案。 缺点&#xff1a; 对于适用同一 Common Clock 作为参考时…

大数据入门(十三)- HDFS的Shell操作

零.HDFS的Shell操作 一.进程启停管理 1.一键启停脚本 Hadoop HDFS组件内置了HDFS集群的一键启停脚本。 1&#xff09;$HADOOP_HOME/sbin/start-dfs.sh&#xff0c;一键启动HDFS集群 执行原理&#xff1a; &#xff08;1&#xff09;在执行此脚本的机器上&#xff0c;启动Secon…

动态规划2:题目

目录 第1题 Fibonacci 第2题 字符串分割(Word Break) .第3题 三角矩阵(Triangle) 第4题 路径总数(Unique Paths) 第5题 最小路径和(Minimum Path Sum) 第6题 背包问题 第7题 回文串分割(Palindrome Partitioning) 第8题 编辑距离(Edit Distance) 第9题 不同子序列(Dist…

Dubbo入门案例

1.基于以下图实现服务 提供者、消费者 2.前期工作 父POM <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLo…

如何在本地安装多个nodejs版本,方便前端开发

目录 &#x1f4dd;一&#xff0c;使用 nvm&#xff08;Node Version Manager&#xff09;: &#x1f4dd;二&#xff0c;使用 n&#xff08;Node.js 版本管理器&#xff09;: &#x1f4e2;要在本地安装多个 Node.js 版本以便于前端开发&#xff0c;你可以使用工具如 nvm&am…

js常用事件

js常用事件如下&#xff1a; onmouseover&#xff1a;鼠标被移到某元素之上&#xff1b; onmouseout&#xff1a;鼠标从某元素移开&#xff1b; onfocus&#xff1a;元素获得焦点&#xff1b; onblur&#xff1a;元素失去焦点&#xff1b; onclick&#xff1a;鼠标单击事件…

蓝桥杯嵌入式STM32G431RBT6竞赛指南与模板——最后的绝唱

谨以此文和我去年前的一篇蓝桥杯单片机的教程构成电子类的青铜双壁. 国信长天单片机竞赛训练之原理图讲解及常用外设原理&#xff08;遗失的章节-零&#xff09;_昊月光华的博客-CSDN博客 目录 时钟树 串口重定向&#xff1a;printf输出 动态点灯(点灯大师) 按键(常用状态…

RabbitMQ学习-发布确认高级

发布确认springboot版本 确认机制方案&#xff1a; 代码架构图&#xff1a; 配置文件&#xff1a; 在application.properties全局配置文件中添加spring.rabbitmq.publish-confirm-type属性&#xff0c;这个属性有以下几种值 none:禁用发布确认模式(默认)0 correlated:发布消…

Redis的SDS+IntSet+Dict

一)SDS 在redis中&#xff0c;保存key的是字符串&#xff0c;value往往是字符串或者是字符串的集合&#xff0c;可见字符串是redis中最常用的一种数据结构: 但是在redis中并没有直接使用C语言的字符串&#xff0c;因为C语言的字符串存在很多问题 1)获取字符串的长度需要通过运算…

算法12.从暴力递归到动态规划5

算法|12.从暴力递归到动态规划5 1.机器人行进问题 题意&#xff1a;假设有排成一行的N个位置记为1~N&#xff0c;N一定大于或等于2 开始时机器人在其中的M位置上(M一定是1~N中的一个) 如果机器人来到1位置&#xff0c;那么下一步只能往右来到2位置&#xff1b; 如果机器人来到…

stc15w404as使用keil做库,提供头文件,供调用

背景 有个项目使用需要使用库&#xff0c;将代码封装起来&#xff0c;仅仅留下调试接口&#xff0c;给用户使用&#xff0c;调试一些参数。这样工程看起来更简单&#xff0c;也方便客户维护。 也有一些使用场景&#xff0c;需要把自己的代码封装起来&#xff0c;这个是怕被别…

电脑msvcp120.dll缺失怎么办?由于找不到msvcp120.dll的解决方案

MSVCP120.dll文件是Windows操作系统中的一种动态链接库文件。它是由Microsoft C软件包提供的重要组件。当系统提示“MSVCP120.dll文件缺失”时&#xff0c;可能会导致某些应用程序无法正常运行。 以下是修复MSVCP120.dll缺失问题的几种方法&#xff1a; 方法一&#xff1a;修复…

如何在华为OD机试中获得满分?Java实现【公共子串计算】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1、题目描述2、输入描述3、输出描述…

<学习笔记>从零开始自学Python-之-web应用框架Django( 十四)上线部署(阿里云+Nginx+uwsgi+MySQL)

好了&#xff0c;我们现在有了一个完整的网站&#xff0c;在自己电脑上跑起来没问题了&#xff0c;但是我们做网站肯定不只是为了在本机上自己欣赏&#xff0c;总要放到网上去让别人来浏览。这一章我们就完整跑一遍Django项目的生产环境部署。 1、基本原理 想让你的网站在公网…

【P38】JMeter 随机控制器(Random Controller)

文章目录 一、随机控制器&#xff08;Random Controller&#xff09;参数说明二、测试计划设计2.1、测试计划一2.2、测试计划二2.3、勾选忽略子控制器块 一、随机控制器&#xff08;Random Controller&#xff09;参数说明 可以让控制器内部的逻辑随机执行一个&#xff0c;一般…

如何在华为OD机试中获得满分?Java实现【24点游戏算法】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1、题目描述2、输入描述3、输出描述…

python自动演奏Freepiano【双手合奏】

文章编写背景 玩了N久的Freepiano,碍于本人没有天赋&#xff0c;左右手一直没法协调。 于是&#xff0c;突然奇想&#xff0c;也是代码设计的思路&#xff1a; 用多线程的方式&#xff0c;开两个线程&#xff0c;然后通过按键模拟的方式&#xff0c;分别模拟左右手去演奏。觉…

分布式网络通信框架(一)——集群和分布式

单机聊天服务器 缺点&#xff1a; 受限于硬件资源&#xff0c;服务器所能承受的用户并发量不够大&#xff1b; 任意模块修改&#xff0c;都会导致整个项目代码重新编译、部署&#xff1b; 系统中&#xff0c;有些模块是CPU密集型&#xff0c;有些是IO密集型&#xff0c;造成…

计算机网络五 传输层

传输层 概念 传输层是指ISO/OSI模型中的第四层&#xff0c;在计算机网络中起着非常重要的作用。它负责数据在网络中的传输&#xff0c;管理数据传输的可靠性和流量控制&#xff0c;保证数据在网络中不会丢失或重复。 提供的服务 传输层提供的主要服务有两种&#xff0c;分别…