动态规划(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;这样的操作会…

刷题记录4.17-5.6

文章目录 刷题记录27.移除元素977.有序数组的平方209.长度最小的子数组707.设计链表206.反转链表24.两两交换链表中的节点19.删除链表的倒数第N个节点142.环形链表II242.有效的字母异位词349.两个数组的交集454.四数相加II18.四数之和151.反转字符串中的单词459.重复的子字符串…

Educational Codeforces Round 165 (Rated for Div. 2) E. Unique Array 贪心+线段树

Unique Array 题目描述 给你一个长度为 n n n 的整数数组 a a a 。 a a a 的子数组是其连续的子序列之一&#xff08;即数组 [ a l , a l 1 , … , a r ] [a_l, a_{l1}, \dots, a_r] [al​,al1​,…,ar​] 中的某个整数 l l l 和 r r r 的子数组 1 ≤ l < r ≤ n …

如何检查 MIDI 文件的安全性

检查 MIDI 文件的安全性通常涉及几个步骤&#xff0c;因为 MIDI 文件本身并不包含可执行代码&#xff0c;所以它们不是传统意义上的恶意软件载体。然而&#xff0c;它们仍然可能以间接的方式带来安全风险&#xff0c;例如通过诱导用户下载与 MIDI 文件一起提供的恶意附件或链接…

JS基础:变量的详解

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

Leetcode181_超过经理收入的员工

1.leetcode原题链接:. - 力扣&#xff08;LeetCode&#xff09; 2.题目描述 表&#xff1a;Employee ---------------------- | Column Name | Type | ---------------------- | id | int | | name | varchar | | salary | int | | manage…

零基础入门学习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…

病毒及网络攻击(信息安全)

一、病毒 计算机病毒的特征&#xff1a;传播性、隐蔽性、感染性、潜伏性、触发性、破坏性等 Worm -- 蠕虫病毒 Trojan -- 特洛伊木马 Backdoor -- 后门病毒 Macro -- 宏病毒 宏病毒 感染的对象主要是 文本文档、电子表格等 木马病毒&#xff1a;冰河 蠕虫病毒&#xff1a;欢乐时…

Java的java.util.concurrent.ExecutorService简介

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

关于排序算法这一篇就够了

排序算法是计算机科学中的一个基本问题&#xff0c;它涉及到将一组数据元素&#xff08;如整数、浮点数、字符串等&#xff09;按照某种顺序&#xff08;如升序或降序&#xff09;进行排列。以下是您提到的几种排序算法的概念和相应的Java实现&#xff1a; 1. 冒泡排序&#x…

已解决javax.sound.sampled.LineUnavailableException异常的正确解决方法,亲测有效!!!

已解决javax.sound.sampled.LineUnavailableException异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 检查音频设备是否被其他应用占用 确认音频格式设置 更新或重装音频驱动…

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

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

vscode查看linux内核代码报错“Unknown argument:“无法跳转函数问题

vscode查看linux内核代码报错问题 现在一直使用bearclangdvscode查看代码&#xff0c; 今天用gcc 9.4.0版本编译Linux 6.6内核代码&#xff0c;编译后发现无法函数跳转。 vscode报错信息如下&#xff1a; Unknown argument: -fconserve-stack Unknown argument: -femit-stru…

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…

MATLAB和Python网格桁架框架构件刚度载荷位移和受力微分方程

&#x1f3af;要点 数学​方法​&#xff1a;&#x1f3af;一维线性边界值问题&#xff1a;&#x1f58a;高斯求积法则 | &#x1f58a;洛巴托求积法则 | &#x1f58a;矩阵插值和微分计算 | &#x1f58a;在细化网格上生成值。&#x1f3af;二维边界值问题&#xff1a;构建二…

Linux--IIC驱动编程实验

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