动态规划(dp)(二)

按摩师

 按摩师

1.状态表示

dp【i】表示:到i位置时,此时最长时长

继续细化:在i位置选预约,或不选预约

f【i】:到i位置时,nums【i】必选的,最长时长

g【i】:到i位置时,nums【i】不选的,最长时长

2状态转移方程

f【i】=g【i-1】+nums【i】

g【i】=max(f【i-1】,g【i-1】)

3初始化

f【0】=nums【0】

g【0】=0

4.填表顺序

左往右

5.返回值

max(f【n-1】,g【n-1】)

class Solution {
public:int massage(vector<int>& nums) {int n=nums.size();if(n==0)return 0;vector<int>f(n);vector<int>g(n);f[0]=nums[0];for(int i=1;i<n;i++){f[i]=g[i-1]+nums[i];g[i]=max(f[i-1],g[i-1]);}return max(f[n-1],g[n-1]);}
};

打家劫舍

198. 打家劫舍

 1.dp表示:

f【i】:表示到i位置时,必偷i位置房屋,获得的最大金额

g【i】:表示到i位置时,不偷i位置房屋,获得的最大金额

f【i】=g【i-1】+nums【i】

g【i】=max(f【i-1】,g【i-1】)

f【0】=nums【0】

返回值

max(f【n-1】,g【n-1】)

class Solution {
public:int rob(vector<int>& nums) {int n =nums.size();vector<int>f(n);vector<int>g(n);f[0]=nums[0];for(int i=1;i<n;i++){f[i]=g[i-1]+nums[i];g[i]=max(f[i-1],g[i-1]);}return max(f[n-1],g[n-1]);}
};

打家劫舍 II

213. 打家劫舍 II

环形问题转化

分情况偷0下标的和不偷0下标的

当偷【0】时,转化为打家劫舍一:从【2,n-2】的打家劫舍

不偷【0】,转化为从【1,n-1】的打家劫舍

class Solution {
public:int rob(vector<int>& nums) {int n=nums.size();if(n==1)return nums[0];else if(n==2)return max(nums[0],nums[1]);else if(n==3)return max(max(nums[0],nums[1]),nums[2]);int a=nums[0]+_rob(nums,2,n-2);int b=_rob(nums,1,n-1);return max(a,b);}int _rob(vector<int>&nums,int left,int right){int n=nums.size();vector<int>f(n);vector<int>g(n);f[left]=nums[left];for(int i=left+1;i<=right;i++){f[i]=g[i-1]+nums[i];g[i]=max(g[i-1],f[i-1]);}return max(f[right],g[right]);}
};

删除并获得点数

740. 删除并获得点数

 转换为打家劫舍问题

用一个arr数组:arr【i】表示i出现的总和


class Solution {
public:const int N=10001;int deleteAndEarn(vector<int>& nums) {int n=nums.size();vector<int>arr(N);for(int v:nums){arr[v]+=v;}vector<int>f(N);vector<int>g(N);for(int i=1;i<N;i++){f[i]=g[i-1]+arr[i];g[i]=max(g[i-1],f[i-1]);}return max(f[N-1],g[N-1]);}
};

粉刷房子

LCR 091. 粉刷房子

dp【i】位置分三种状态,

分别时刷红,蓝,绿

用dp【i】【0,1,2】分别表示到第i位置时,刷红蓝绿的成本

class Solution {
public:int minCost(vector<vector<int>>& costs) {int n=costs.size();vector<vector<int>>dp(n,vector<int>(3));dp[0][0]=costs[0][0];dp[0][1]=costs[0][1];dp[0][2]=costs[0][2];for(int i=1;i<n;i++){dp[i][0]=min(dp[i-1][1],dp[i-1][2])+costs[i][0];dp[i][1]=min(dp[i-1][0],dp[i-1][2])+costs[i][1];dp[i][2]=min(dp[i-1][1],dp[i-1][0])+costs[i][2];}return min(dp[n-1][2],min(dp[n-1][0],dp[n-1][1]));}
};

 309. 买卖股票的最佳时机含冷冻期

买卖股票的最佳时机含冷冻期

309. 买卖股票的最佳时机含冷冻期

状态转移:

状态机:可买(可交易)dp【0】,可卖(买入)dp【1】,冷冻期dp【2】

dp【i】【0】=max(dp【i-1】【0】,dp【i-1】【2】)

dp【i】【1】=max(dp【i-1】【0】-costs【i】,dp【i-1】【1】)

dp【i】【2】=dp【i-1】【1】+costs【i】

初始化

dp【0】【0】=0

dp【0】【1】=-cost【0】

dp【0】【2】=0

class Solution {
public:int maxProfit(vector<int>& prices) {int n=prices.size();vector<vector<int>>dp(n,vector<int>(3));dp[0][1]=-prices[0];for(int i=1;i<n;i++){dp[i][0]=max(dp[i-1][0],dp[i-1][2]);dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);dp[i][2]=dp[i-1][1]+prices[i];}return max(dp[n-1][0],dp[n-1][2]);}
};

买卖股票的最佳时机含手续费

714. 买卖股票的最佳时机含手续费

dp【i】【0】可买

dp【i】【1】可卖

dp【i】【0】=max(dp【i-1】【0】,dp【i-1】【1】+prices【i】-fee)

dp【i】【1】=max(dp【i-1】【1】,dp【i-1】【0】-prices【i】)

dp【0】【0】=0

dp【0】【1】=-prices【0】

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {int n=prices.size();vector<vector<int>>dp(n,vector<int>(3));dp[0][1]=-prices[0];for(int i=1;i<n;i++){dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);}return dp[n-1][0];}
};

123. 买卖股票的最佳时机 III

188. 买卖股票的最佳时机 IV

122. 买卖股票的最佳时机 II

122. 买卖股票的最佳时机 II

dp【i】【0】可买

dp【i】【1】可卖

dp【i】【0】=max(dp【i-1】【0】,dp【i-1】【1】+prices【i】)

dp【i】【1】=max(dp【i-1】【1】,dp【i-1】【0】-prices【i】)

dp【0】【0】=0

dp【0】【1】=-prices【0】

class Solution {
public:int maxProfit(vector<int>& prices) {int n=prices.size();vector<vector<int>>dp(n,vector<int>(2));dp[0][1]=-prices[0];for(int i=1;i<n;i++){dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);}return dp[n-1][0];}
};

121. 买卖股票的最佳时机

53. 最大子数组和

53. 最大子数组和

dp【i】:以i位置为结尾的所有子数组最大和

fen为长度为1和不为1的

dp【i】=max(dp【i-1】+nums【i】,nums【i】)

class Solution {
public:int maxSubArray(vector<int>& nums) {int n=nums.size();vector<int>dp(n);dp[0]=nums[0];for(int i=1;i<n;i++){dp[i]=max(dp[i-1]+nums[i],nums[i]);}int ret=INT_MIN;for(int i=0;i<n;i++){ret=max(ret,dp[i]);}return ret;}
};

918. 环形子数组的最大和

918. 环形子数组的最大和

借鉴环形打家劫舍

转化为非环形

f【i】:以i位置为结尾的所有子数组最大和

g【i】:以i位置为结尾的所有子数组最小和

返回 f【i】和sum-g【i】中最大的

注意:当全为负数时 f【i】为负

sum-g【i】为0,会返回0 这是错误的结果

class Solution {
public:int maxSubarraySumCircular(vector<int>& nums) {int n=nums.size();vector<int>f(n);vector<int>g(n);f[0]=nums[0];g[0]=nums[0];int sum=0;for(int i=1;i<n;i++){f[i]=max(f[i-1]+nums[i],nums[i]);g[i]=min(g[i-1]+nums[i],nums[i]);}for(auto v:nums){sum+=v;}int Max=f[0];for(int i=1;i<n;i++){if(i==n-1&&sum-g[i]==0){if(Max<f[i])Max=f[i];break;}if(Max<f[i])Max=f[i];if(Max<(sum-g[i]))Max=sum-g[i];}return Max;}
};

乘积最大子数组

乘积最大子数组

f【i】以i为结尾的乘积最大的子数组

g【i】以i为结尾的乘积最小的子数组

f【i】=

1.nums【i】

2.

乘积要分类 nums【i】》0,要与f【i-1】相乘

nums【i】《0,要与g【i-1】相乘

f【i】=max(nums【i】,f【i-1】*nums【i】,g【i-1】*nums【i】)

g【i】=min(nums【i】,f【i-1】*nums【i】,g【i-1】*nums【i】)

class Solution {
public:int maxProduct(vector<int>& nums) {int n=nums.size();vector<vector<int>>dp(n,vector<int>(2));dp[0][0]=nums[0];dp[0][1]=nums[0];int Max=INT_MIN;for(int i=1;i<n;i++){dp[i][0]=max(dp[i-1][0]*nums[i],max(nums[i],dp[i-1][1]*nums[i]));dp[i][1]=min(dp[i-1][1]*nums[i],min(nums[i],dp[i-1][0]*nums[i]));}for(int i=0;i<n;i++){Max=Max>dp[i][0]?Max:dp[i][0];}return Max;}
};

乘积为正数的最长子数组长度

乘积为正数的最长子数组长度

f【i】以i为结尾乘积为正数的最长子数组长度

g【i】以i为结尾乘积为负数数的最长子数组长度

分类

1.nums【i】==0 f【i】==0

2.nums【i】<0

f【i】=g【i-1】+1   

要单独判断f【i-1】=0

g【i】=f【i-1】+1

2.nums【i】>0

要单独判断g【i-1】=0

 f【i】=f【i-1】+1   

g【i】=g【i-1】+1

class Solution {
public:int getMaxLen(vector<int>& nums) {int n=nums.size();vector<vector<int>>dp(n+1,vector<int>(2));dp[0][0]=0;dp[0][1]=-1;int Max=0;for(int i=1;i<=n;i++)if(nums[i-1]==0)dp[i][0]=dp[i][1]=0;else if(nums[i-1]<0){if(dp[i-1][1]==0)dp[i][0]=0;elsedp[i][0]=dp[i-1][1]+1;dp[i][1]=dp[i-1][0]+1;}else{dp[i][0]=dp[i-1][0]+1;if(dp[i-1][1]==0)dp[i][1]=0;elsedp[i][1]= dp[i-1][1]+1;}for(int i=1;i<=n;i++)Max=Max>dp[i][0]?Max:dp[i][0];return Max;}
};

等差数列划分

等差数列划分

dp【i】以i位置为结尾的能构成等差数列的个数

dp【i】

1.nums【i】+nums【i-2】=nums【i-1】*2

dp【i】=1+dp【i-1】

2

dp【i】=0

class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {int n=nums.size();vector<int>dp(n);if(n==1||n==2)return 0;dp[0]=dp[1]=0;for(int i=2;i<n;i++){if(nums[i]+nums[i-2]==2*nums[i-1])dp[i]=1+dp[i-1];elsedp[i]=0;}int sum=0;for(int i=0;i<n;i++){sum+=dp[i];}return sum;}
};

最长湍流子数组

最长湍流子数组

f【i】表示以i为结尾的最长湍流子数组 且i位置为小

g【i】表示以i为结尾的最长湍流子数组 且i位置为大

f【i】=g【i】=1

if(nums【i-1】> nums【i】)

        f【i】=1+g【i-1】

else if (nums【i-1】<nums【i】)

        g【i】=1+f【i-1】

else 

        f【i】=g【i】=1

class Solution {
public:int maxTurbulenceSize(vector<int>& arr) {int n=arr.size();vector<int>f(n);vector<int>g(n);f[0]=g[0]=1;int Max=INT_MIN;for(int i=1;i<n;i++){if(arr[i-1]>arr[i]){f[i]=g[i-1]+1;g[i]=1;}else if(arr[i-1]<arr[i]){g[i]=f[i-1]+1;f[i]=1;}else{f[i]=g[i]=1;}}for(int i=0;i<n;i++){Max=Max>f[i]?Max:f[i];Max=Max>g[i]?Max:g[i];}return Max;}
};

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

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

相关文章

仅为娱乐,Python中如何重定义True为False?

在Python中&#xff0c;True 和 False 是内建的布尔常量&#xff0c;分别代表逻辑上的真和假。它们是不可变的&#xff0c;且在Python语言规范中具有特殊地位&#xff0c;不能被用户直接重定义。尝试给 True 或 False 赋予新的值是违反Python语言规则的&#xff0c;这样的操作会…

JS基础:变量的详解

你好&#xff0c;我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃&#xff0c;大专生&#xff0c;一枚程序媛&#xff0c;感谢关注。回复 “前端基础题”&#xff0c;可免费获得前端基础 100 题汇总&#xff0c;回复 “前端基础路线”&#xff0c;可获取…

零基础入门学习Python第二阶01生成式(推导式),数据结构

Python语言进阶 重要知识点 生成式&#xff08;推导式&#xff09;的用法 prices {AAPL: 191.88,GOOG: 1186.96,IBM: 149.24,ORCL: 48.44,ACN: 166.89,FB: 208.09,SYMC: 21.29}# 用股票价格大于100元的股票构造一个新的字典prices2 {key: value for key, value in prices.i…

Java的java.util.concurrent.ExecutorService简介

在Java并发编程的璀璨星空中&#xff0c;ExecutorService无疑是那颗最耀眼的明星。它不仅是Java并发编程的核心组件之一&#xff0c;更是构建高并发、高性能应用的秘密武器。今天&#xff0c;我们就来一场说走就走的探索之旅&#xff0c;揭开它的神秘面纱&#xff01; &#x1…

深度学习中的不确定性量化:技术、应用和挑战综述(一)

不确定性量化(UQ)在减少优化和决策过程中的不确定性方面起着关键作用&#xff0c;应用于解决各种现实世界的科学和工程应用。贝叶斯近似和集成学习技术是文献中使用最广泛的两种UQ方法。在这方面&#xff0c;研究人员提出了不同的UQ方法&#xff0c;并测试了它们在各种应用中的…

Ansible自动化运维工具单模块介绍

前言 自动化运维是指利用自动化工具和技术来简化、自动化和优化IT基础设施的管理和运维过程&#xff0c;从而提高效率、降低成本&#xff0c;并减少人为错误。在当今复杂的IT环境中&#xff0c;自动化运维已经成为许多组织和企业提高生产力和保证系统稳定性的重要手段。Ansibl…

动态规划算法:路径问题

例题一 解法&#xff08;动态规划&#xff09;&#xff1a; 算法思路&#xff1a; 1. 状态表⽰&#xff1a; 对于这种「路径类」的问题&#xff0c;我们的状态表⽰⼀般有两种形式&#xff1a; i. 从 [i, j] 位置出发&#xff0c;巴拉巴拉&#xff1b; ii. 从起始位置出…

使用Simcenter全面评估SiC 器件的特性

内容摘要 传统的硅金属-氧化物-半导体场效应晶体管 (MOSFET) 具有成熟的技术和低廉的成本&#xff0c;在中压和绝缘栅双极晶体管 (IGBT) 高压功率电子器件中占主导地位。使用碳化硅等具有高电离能的新型宽带隙材料&#xff0c;可以制造出具有快速开关时间和超过1,000伏击穿电压…

博客网站SpringBoot+Vue项目练习

博客网站SpringBootVue简单案例 前言 学了vue后一直没用找到应用的机会&#xff0c;在Github上找到了一个看起来比较友好的项目&#xff08;其实具体代码我还没看过&#xff09;。而且这个项目作者的readme文档写的也算是比较好的了。 项目链接&#xff1a;https://github.c…

【LeetCode刷题】739. 每日温度(单调栈)

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 739. 每日温度 2. 题目描述 3. 解题方法 用一个栈st保存每个数的下标&#xff0c;同时创建一个数组res保存结果&#xff0c;初始值都为0。循环遍历题目中的数组temperature。如果temperature[i] > st.top()&#x…

Linux--IIC驱动编程实验

对于 I2C 主机驱动&#xff0c;一旦编写完成就不需要再做修改&#xff0c;其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想&#xff0c;因此 Linux内核也将 I2C 驱动分为两部分&#xff1a; ①、 I2C 总…

虚拟化之---virtio通信

一、理解virtio的背景 我们知道虚拟化hypervisor大的类型分为两种&#xff0c;全虚拟化和半虚拟化。 在全虚拟化的解决方案中&#xff0c;guest VM 要使用底层 host 资源&#xff0c;需要 Hypervisor 来截获所有的请求指令&#xff0c;然后模拟出这些指令的行为&#xff0c;这样…

Java毕设之学院党员管理系统的设计与实现

运行环境 环境说明: 开发语言:java 框架:springboot&#xff0c;vue JDK版本:JDK1.8 数据库:mysql5.7(推荐5.7&#xff0c;8.0也可以) 数据库工具:Navicat11 开发软件:idea/eclipse(推荐idea) Maven包:Maven3.3.9 系统实现 管理员功能实现 党员管理 管理员进入指定功能操作…

算法学习:二分查找

&#x1f525; 引言 在现代计算机科学与软件工程的实践中&#xff0c;高效数据检索是众多应用程序的核心需求之一。二分查找算法&#xff0c;作为解决有序序列查询问题的高效策略&#xff0c;凭借其对数时间复杂度的优越性能&#xff0c;占据着算法领域里举足轻重的地位。本篇内…

如何使用resource-counter统计跨Amazon区域的不同类型资源数量

关于resource-counter resource-counter是一款功能强大的命令行工具&#xff0c;该工具基于纯Python 3开发&#xff0c;可以帮助广大研究人员跨Amazon区域统计不同类型资源的数量。 该工具在统计完不同区域的各类资源数量后&#xff0c;可以在命令行中输出并显示统计结果。res…

【driver5】调用堆栈函数,printk,动态打印,ftrace,proc,sysfs

文章目录 1.内核函数调用堆栈&#xff1a;4个函数2.printk&#xff1a;cat /proc/cmdline查看consolettyS03.动态打印&#xff1a;printk是全局的且只能设打印等级&#xff0c;动态打印可控制选择模块的打印&#xff0c;在内核配置打开CONFIG_DYNAMIC_DEBUG4.ftrace&#xff1a…

贪吃蛇项目(小白保姆级教程)

游戏介绍 游戏背景&#xff1a; 贪吃蛇游戏是经典的游戏项目之一&#xff0c;也是很简单的小游戏 实现背景&#xff1a; 这里我们是基于32位的Win32_API进行实现的 需要的知识点&#xff1a; C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32_API等 适合人群&a…

分布式光伏管理系统和一般的光伏管理系统相比有什么区别?

随着全球对可再生能源的关注度日益提高&#xff0c;光伏技术作为其中的佼佼者&#xff0c;已经得到了广泛的应用。在光伏技术中&#xff0c;管理系统扮演着至关重要的角色&#xff0c;它关乎着光伏电站的运行效率、能源产出以及运维成本等多个方面。其中&#xff0c;分布式光伏…

搜索算法系列之四(斐波那契)

以下算法被验证过&#xff0c;如有什么问题或有补充的欢迎留言。 前言 斐波那契数列&#xff0c;又称黄金分割数列&#xff0c;是由意大利数学家&#xff08;Leonardo Fibonacci&#xff09;在1202年提出的。这个数列的递推关系是F(0)1&#xff0c;F(1)1&#xff0c;F(n)F(n-…

【数据库】docker搭建mysql8一主两从节点,配置proxysql读写分离

docker搭建mysql8一主两从节点&#xff0c;配置proxysql读写分离 一、docker 搭建 mysql8 一主两从节点1.1 相关配置文件与docker启动1.2 半同步复制1.3 主从同步异常处理 二、mysql 中间件 ProxySql 配置读写分离2.1 在mysql服务里创建给proxySQL访问的用户2.2 安装ProxySql及…