数据结构与算法:区间dp

前言

区间dp也是动态规划里很重要的一部分。

一、内容

区间dp的根本原理就是把大范围问题分解成若干小范围的问题去求解。一般来讲,常见的用法有对于两侧端点去展开可能性和对于范围上的划分点去展开可能性。

二、题目

1.让字符串成为回文串的最少插入次数

class Solution {
public:int minInsertions(string s) {//return recursion(0,s.length()-1,s);// vector<vector<int>>dp(s.length(),vector<int>(s.length(),-1));// return ms(0,s.length()-1,s,dp);// return DP(s);return optimized_dp(s);}//递归尝试 -> 超时int recursion(int i,int j,string &s){if(i==j){return 0;}if(i+1==j){return s[i]==s[j]?0:1;}if(s[i]==s[j]){return recursion(i+1,j-1,s);}else{return min(recursion(i+1,j,s),recursion(i,j-1,s))+1;}}//记忆化搜索int ms(int i,int j,string &s,vector<vector<int>>&dp){if(i==j){return 0;}if(i+1==j){return s[i]==s[j]?0:1;}if(dp[i][j]!=-1){return dp[i][j];}if(s[i]==s[j]){dp[i][j]=ms(i+1,j-1,s,dp);return dp[i][j];}else{dp[i][j]=min(ms(i+1,j,s,dp),ms(i,j-1,s,dp))+1;return dp[i][j];} }//动态规划int DP(string &s){int n=s.length();vector<vector<int>>dp(n,vector<int>(n));//初始化for(int i=0;i<n-1;i++){dp[i][i+1]=s[i]==s[i+1]?0:1;}for(int i=n-3;i>=0;i--){for(int j=i+2;j<n;j++){if(s[i]==s[j]){dp[i][j]=dp[i+1][j-1];}else{dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1;}}}return dp[0][n-1];}//空间压缩int optimized_dp(string &s){int n=s.length();//特例if(n<2){return 0;}vector<int>dp(n);dp[n-1]=s[n-2]==s[n-1]?0:1;for(int i=n-3,leftDown,tmp;i>=0;i--){leftDown=dp[i+1];dp[i+1]=s[i]==s[i+1]?0:1;for(int j=i+2;j<n;j++){tmp=dp[j];if(s[i]==s[j]){dp[j]=leftDown;}else{dp[j]=min(dp[j],dp[j-1])+1;}leftDown=tmp;}}return dp[n-1];}
};

这个题就是区间dp的第一个用法,就是去两端点展开可能性。能想到区间dp从两端展开就是因为要求是回文串。

首先还是从递归尝试入手,basecase就是当两端指针来到同一个字符时,那自己就能构成回文串,所以返回0;如果两指针相邻,那如果两字符相同就是0,不同就是1,即需要插入一次。之后就讨论当前字符对没对上,对上了就直接去之后递归;没对上就讨论插入左侧和右侧两种情况。

记忆化搜索直接挂个dp表即可。

动态规划直接观察严格位置依赖即可,那就是左下、左和下。

空间压缩时因为依赖左下的格子,所以每次要用一个leftDown记录左下。

2.预测赢家

class Solution {
public:bool predictTheWinner(vector<int>& nums) {int n=nums.size();int sum=0;for(int num:nums){sum+=num;}int first;// first=recursion(0,n-1,nums);// vector<vector<int>>dp(n,vector<int>(n,-1));// first=MS(0,n-1,nums,dp);first=DP(nums);int second=sum-first;return first>=second;}//递归尝试int recursion(int l,int r,vector<int>&nums){if(l==r){return nums[l];}if(l+1==r){return max(nums[l],nums[r]);}int p1=nums[l]+min(recursion(l+2,r,nums),recursion(l+1,r-1,nums));int p2=nums[r]+min(recursion(l,r-2,nums),recursion(l+1,r-1,nums));return max(p1,p2);}//记忆化搜索int MS(int l,int r,vector<int>&nums,vector<vector<int>>&dp){if(l==r){return nums[l];}if(l+1==r){return max(nums[l],nums[r]);}if(dp[l][r]!=-1){return dp[l][r];}int p1=nums[l]+min(MS(l+2,r,nums,dp),MS(l+1,r-1,nums,dp));int p2=nums[r]+min(MS(l,r-2,nums,dp),MS(l+1,r-1,nums,dp));dp[l][r]=max(p1,p2);return dp[l][r];}//动态规划int DP(vector<int>&nums){int n=nums.size();vector<vector<int>>dp(n,vector<int>(n));//初始化for(int i=0;i<n;i++){dp[i][i]=nums[i];if(i+1<n){dp[i][i+1]=max(nums[i],nums[i+1]);}}for(int i=n-3;i>=0;i--){for(int j=i+2;j<n;j++){int p1=nums[i]+min(dp[i+2][j],dp[i+1][j-1]);int p2=nums[j]+min(dp[i][j-2],dp[i+1][j-1]);dp[i][j]=max(p1,p2);}}return dp[0][n-1];}
};

这个题需要一点小思考,想明白了就好写了。

首先是对于两人的得分,并不需要分别计算,只需要算出累加和后,计算一个人的得分,那么另一个人的就是累加和减去这个人的得分。

之后是求这一个人的最大得分。分析博弈的过程,可以发现,当前的人肯定是分成拿左侧和拿右侧两种情况,而选择的逻辑可以从让自己尽可能大转化成让对手尽可能小。所以对手肯定会尽可能让自己小,那就是两种情况再加上

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

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

相关文章

AI Agent 入门指南:从 LLM 到智能体

AI. AI. AI. 最近耳朵里是不是总是被这些词轰炸&#xff1f;特别是“Agent”、“AI Agent”、“智能体”、“Agentic”…… 感觉一夜之间&#xff0c;AI 就从我们熟悉的聊天框里蹦出来&#xff0c;要拥有“独立思考”和“自主行动”的能力了&#xff1f; 说实话&#xff0c;一…

开启docker中mysql的binlog日志

1.登陆docker服务器,输入docker ps查看服务: 2.进入mysql服务 进入到mysql的服务容器后,输入mysql -u*** -p***登陆 mysql 客户端查看是否开启binlog 输入 : show variables like log_bin; 3.输入quit退出mysql客户端 4.之后在docker的mysql服务容器里查询mysql的配置文件所在…

Kotlin 中 List 和 MutableList 的区别

在 Kotlin 中&#xff0c;List 和 MutableList 是两种不同的集合接口&#xff0c;核心区别在于可变性。 Kotlin 集合框架的重要设计原则&#xff1a;通过接口分离只读&#xff08;read - only&#xff09;和可变&#xff08;mutable&#xff09;操作&#xff0c;以提高代码的安…

【能力比对】K8S数据平台VS数据平台

&#x1f525;&#x1f525; AllData大数据产品是可定义数据中台&#xff0c;以数据平台为底座&#xff0c;以数据中台为桥梁&#xff0c;以机器学习平台为中层框架&#xff0c;以大模型应用为上游产品&#xff0c;提供全链路数字化解决方案。 ✨AllData数据中台官方平台&…

Fastjson 从多层级的JSON数据中获取特定字段的值

使用 Fastjson 的 JSONPath.eval 可以通过 JSONPath 表达式直接定位多层级 JSON 中的目标字段&#xff0c;避免逐层调用 getJSONObject() 的繁琐操作。以下是具体实现方法和示例&#xff1a; 核心思路 通过 JSONPath.eval 方法&#xff0c;传入 JSON 对象&#xff08;或 JSON…

端口安全基本配置

1.top图 2.交换机配置 交换机swa <SWA> system-view [SWA] vlan batch 10 20[SWA] interface GigabitEthernet0/0/1 [SWA-GigabitEthernet0/0/1] port link-type trunk [SWA-GigabitEthernet0/0/1] port trunk allow-pass vlan 10[SWA] interface GigabitEthernet0/0/2 …

hadoop集群建立

建立Hadoop集群的步骤指南 建立Hadoop集群需要系统规划和多个步骤的配置。以下是详细的建立流程&#xff1a; 一、前期准备 硬件需求 多台服务器(至少3台&#xff0c;1主2从) 每台建议配置&#xff1a;至少4核CPU&#xff0c;8GB内存&#xff0c;100GB硬盘 稳定的网络连接(…

从零开始学java--集合类(2)

集合类 目录 集合类 Queue 队列的使用&#xff1a; 双端队列&#xff08;Deque&#xff09; Map和Set 概念&#xff1a; 模型&#xff1a; Map 常见方法说明&#xff1a; 注意&#xff1a; TreeMap和HashMap的区别&#xff1a; Set 常见方法说明&#xff1a; 注…

【HarmonyOS 5】鸿蒙发展历程

【HarmonyOS 5】鸿蒙发展历程 一、鸿蒙 HarmonyOS 版本年代记 鸿蒙 1.0&#xff1a; 2019 年 8 月 9 日&#xff0c;华为在开发者大会上正式发布鸿蒙 1.0 系统&#xff0c;这一版本首次应用于华为荣耀智慧屏产品中&#xff0c;标志着华为正式进军操作系统领域。该版本初步展现…

SpringBoot教学管理平台源码设计开发

概述 基于SpringBoot框架开发的​​教学管理平台​​完整项目&#xff0c;帮助开发者快速搭建在线教育平台。该系统包含学生端、教师端和管理后台&#xff0c;实现了课程管理、随堂测试、作业提交等核心功能&#xff0c;是学习SpringBoot开发的优质案例。 主要内容 1. 系统架…

人工智能端侧热度再起

在科技浪潮汹涌澎湃的当下,人工智能端侧正悄然掀起新一轮的热度风暴。曾经,人工智能更多停留在概念层面,仿佛是遥不可及的未来幻想;而后,它逐渐落地,在特定领域崭露头角,却也显得有些曲高和寡。但如今,人工智能端侧正以前所未有的态势融入我们的生活,从智能手机的语音…

相同的数(简单)

深度优先搜索 如果两个二叉树都为空&#xff0c;则两个二叉树相同。如果两个二叉树中有且只有一个为空&#xff0c;则两个二叉树一定不相同。 如果两个二叉树都不为空&#xff0c;那么首先判断它们的根节点的值是否相同&#xff0c;若不相同则两个二叉树一定不同&#xff0c;…

网络安全等级保护有关工作事项[2025]

公安部发布公网安〔2025〕1846号文件&#xff0c;关于对网络安全等级保护有关共工作事项的进一步说明 一、备案相关问题 1、如何执行系统备案动态更新工作? 全面梳理与重新填报&#xff1a; 答复&#xff1a;运营者需**全面梳理已备案系统**的情况&#xff0c;对于已完成定…

c++类【发展】

类的静态成员&#xff08;用static声明的成员&#xff09;,在声明之外用例单独的语句进行初始化&#xff0c;初始化时&#xff0c;不再需要用static进行限定。在方法文件中初始化。以防重复。 特殊成员函数 复制构造函数&#xff1a; 当使用一个对象来初始化另一个对象…

宁德时代区块链+数字孪生专利解析:去中心化身份认证重构产业安全底座

引言&#xff1a;当动力电池巨头瞄准数字孪生安全 2025年5月6日&#xff0c;金融界披露宁德时代未来能源&#xff08;上海&#xff09;研究院与母公司宁德时代新能源科技股份有限公司联合申请的一项关键专利——“身份验证方法、系统、电子设备及存储介质”。这项技术将区块链…

cesium之自定义地图与地图叠加

在appvue中,cesium支持更换不同的地图资源,代码如下 <template><div id"cesiumContainer" ref"cesiumContainer"></div> </template><script setup> import * as Cesium from cesium; import "./Widgets/widgets.css&…

STL?string!!!

一、引言 在之前的文章中&#xff0c;我们一同学习了有关类和对象、模板、动态内存管理的相关知识&#xff0c;那么接下来一段时间我们将要趁热打铁&#xff0c;一起来手撕C库中最重要的一个库----STL中的一些容器&#xff0c;在手撕它们之前&#xff0c;我将先介绍一下对应的容…

低版本GUI配置SAProuter

1、注意配置SAProuter时&#xff0c;必须添加后面的/H/ 如&#xff1a;/H/sap.sapzx.cn/H/ 2、或者有时需要配置service文件&#xff08;C:\WINDOWS \system32\drivers\etc\service&#xff09; sapmsEP1 3600/tcp

springBoot中自定义一个validation注解,实现指定枚举值校验

缘由 在后台写接口的时候&#xff0c;经常会出现dto某个属性是映射到一个枚举的情况。有时候还会出现只能映射到枚举类中部分枚举值的情况。以前都是在service里面自行判断&#xff0c;很多地方代码冗余&#xff0c;所以就想着弄一个自定义的validation注解来实现。 例如下面某…

MySQL数据库中篇

#作者&#xff1a;允砸儿 #日期&#xff1a;乙巳青蛇年 四月初九 笔者继续带朋友们了解mysql数据库中篇的内容。多了不说&#xff0c;少了不唠&#xff0c;咱们直接就开写。 书接上回笔者在上篇中介绍了什么是数据库和数据库的一些基础的概念&#xff0c;以及mysql数据库的…