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

深圳知名网站建设平台优秀网站设计网站

深圳知名网站建设平台,优秀网站设计网站,网站后台制作视频教程,自做网站一. 按摩师 按摩师 状态表示 根据经验 题目要求 dp[i] 表示: 选择到i位置时, 此时的最长预约时长 但是根据题目又分成两种情况: f[i] : 选择到 i 位置的时候, nums[i] 必选, 此时的最长预约时长 g[i] : 选择到 i 位置的时候, nums[i] 不选, 此时的最长预约时长状态转移方程 …

一. 按摩师

按摩师

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到i位置时, 此时的最长预约时长
    但是根据题目又分成两种情况:
    f[i] : 选择到 i 位置的时候, nums[i] 必选, 此时的最长预约时长
    g[i] : 选择到 i 位置的时候, nums[i] 不选, 此时的最长预约时长
  2. 状态转移方程
    f[i] 如果i 位置必选, 那么f[i - 1] 位置必不选, 就等于g[i - 1] + nums[i]
    g[i] 如果i位置不选, 那么g[i - 1] 位置有两种情况, 如果[i - 1] 选, 那么就=f[i - 1] ,如果[i - 1] 不选, 那么就=g[i - 1] , 但是我们要的是最长时长, 所以
  • f[i] = g[i - 1] + nums[i]
  • g[i] = max(f[i - 1], g[i - 1])
  1. 初始化
    f[0] = nums[0] g[0] = 0;
  2. 填表顺序
    从左往右 两个表一起填
  3. 返回值
    返回max(f[n], g[n])
class Solution {public int massage(int[] nums) {//1. 建表//2. 初始化//3. 填表//4. 返回值int n = nums.length;if(n == 0) return 0;int[] f = new int[n];int[] g = new int[n];f[0] = nums[0];for(int i = 1; i < n; i++){f[i] = g[i - 1] + nums[i];g[i] = Math.max(f[i - 1], g[i - 1]);}return Math.max(f[n - 1], g[n - 1]);}
}

二. 打家劫舍II

打家劫舍II
分析: 通过分类讨论, 可以将环形的问题转化为线性问题
1.如果第0家偷, 那么第一家和最后一家就不能偷, 所以第二家和倒数第二家之间就可以按照正常的情况考虑
2.如果第0家不偷, 那么剩下的都可以正常进行了

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到i位置时, 此时偷的最大金额
    但是根据题目又分成两种情况:
    f[i] : 选择到 i 位置的时候, nums[i] 必选, 此时偷的最大金额
    g[i] : 选择到 i 位置的时候, nums[i] 不选, 此时偷的最大金额
  2. 状态转移方程
    f[i] 如果i 位置必选, 那么f[i - 1] 位置必不选, 就等于g[i - 1] + nums[i]
    g[i] 如果i位置不选, 那么g[i - 1] 位置有两种情况, 如果[i - 1] 选, 那么就=f[i - 1] ,如果[i - 1] 不选, 那么就=g[i - 1] , 但是我们要的是偷的最大金额, 所以
  • f[i] = g[i - 1] + nums[i]
  • g[i] = max(f[i - 1], g[i - 1])
  1. 初始化
    f[0] = nums[0] g[0] = 0;
  2. 填表顺序
    从左往右 两个表一起填
  3. 返回值
    返回第0家偷和不偷的最大值
class Solution {int[] f;int[] g;int[] nums;public int rob(int[] _nums) {// 1. 建表// 2. 初始化// 3. 填表// 4. 返回值nums = _nums;int n = _nums.length;int x = rob1(2, n - 2) + nums[0];int y = rob1(1, n - 1);return Math.max(x, y);}public int rob1(int left, int right) {if(left > right) return 0;int n = nums.length;f = new int[n];g = new int[n];f[left] = nums[left];for (int i = left; i <= right; i++) {f[i] = g[i - 1] + nums[i];g[i] = Math.max(g[i - 1], f[i - 1]);}return Math.max(f[right], g[right]);}}

三. 删除并获得点数

删除并获得点数
分析: 由于是删除大于或和小于的数, 也就是说相邻的数是不能再选的, 那么和打家劫舍问题是类似的
但是这些数并不是相邻的并且无序, 所以我们需要重新定义一个数组arr来存储
点数代表下标, 对应的值就是该点数的总和

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到i位置时, 此时获得的最大点数
    但是根据题目又分成两种情况:
    f[i] : 选择到 i 位置的时候, nums[i] 必选, 此时获得的最大点数
    g[i] : 选择到 i 位置的时候, nums[i] 不选, 此时获得的最大点数
  2. 状态转移方程
    f[i] 如果i 位置必选, 那么f[i - 1] 位置必不选, 就等于g[i - 1] + arr[i]
    g[i] 如果i位置不选, 那么g[i - 1] 位置有两种情况, 如果[i - 1] 选, 那么就=f[i - 1] ,如果[i - 1] 不选, 那么就=g[i - 1] , 但是我们要的是获得的最大点数, 所以
  • f[i] = g[i - 1] + nums[i]
  • g[i] = max(f[i - 1], g[i - 1])
  1. 初始化
    f[0] = arr[0] g[0] = 0;
  2. 填表顺序
    从左往右 两个表一起填
  3. 返回值
    返回max(f[n - 1], g[n - 1])
class Solution {public int deleteAndEarn(int[] nums) {//预处理int n = 10001;int[] arr = new int[n];for(int x: nums) arr[x] += x;//建表//初始化//填表//返回值int[] f = new int[n];int[] g = new int[n];f[0] = arr[0];for(int i = 1; i < n; i++){f[i] = g[i - 1] + arr[i];g[i] = Math.max(f[i - 1], g[i - 1]);}return Math.max(f[n - 1], g[n - 1]);}
}

四, 粉刷房子

粉刷房子

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到i位置时, 此时粉刷的最小花费
    但是根据题目又分成两种情况:
    如果第i个房子, 粉刷的是红色的, 那么前一个房子只能是蓝色或绿色, 同理其他情况
    所以dp可以弄成二维数组, dp[i][j] 表示最小费用, j表示颜色 0红色,1蓝色,2绿色
  2. 状态转移方程
    1.如果i选择红色, dp[i][0], 那么dp[i - 1]只能选择[1][2], 要的是最小花费, 所以
  • dp[i][0] = Math.min(dp[i - 1][1], dp[i - 1][2]) + costs[i - 1][0]

2.如果i选择蓝色, dp[i][0], 那么dp[i - 1]只能选择[1][2], 要的是最小花费, 所以

  • dp[i][1] = Math.min(dp[i - 1][0], dp[i - 1][2]) + costs[i - 1][1]

3.如果i选择红色, dp[i][0], 那么dp[i - 1]只能选择[1][2], 要的是最小花费, 所以

  • dp[i][2] = Math.min(dp[i - 1][0], dp[i - 1][1]) + costs[i - 1][2]
  1. 初始化
    本道题初始化较为复杂, 所以使用虚拟节点来帮助我们初始化, 要注意两个注意事项: 初始化与对应关系
    最开始是0的位置最小花费应该初始化为0, 因为还没有花费
  2. 填表顺序
    从左往右 两个表一起填
  3. 返回值
    返回min(dp[n][0], dp[n][1], dp[n][2])
class Solution {public int minCost(int[][] costs) {int n = costs.length;int[][] dp = new int[n + 1][3];for(int i = 1; i <= n; i++){//i遍历的是行dp[i][0] = Math.min(dp[i - 1][1], dp[i - 1][2]) + costs[i - 1][0];dp[i][1] = Math.min(dp[i - 1][0], dp[i - 1][2]) + costs[i - 1][1];dp[i][2] = Math.min(dp[i - 1][0], dp[i - 1][1]) + costs[i - 1][2];}return Math.min(Math.min(dp[n][0], dp[n][1]), dp[n][2]);}
}

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

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

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到第i天位置时, 此时的最大利润
    但是到第i天又分成三种情况:
    可能处于"买入"状态, "可交易"状态, "冷冻期"状态
    所以用二维数组[i][j]状态表示 0"买入"状态, 1"可交易"状态, 2"冷冻期"状态
  2. 状态转移方程
    1.如果处于"买入"状态, 那么第i - 1天, 可能处于"买入"状态(i - 1天买完后第i天没卖, 等于啥也没干), 可能处于"可交易"状态(i - 1天不是冷冻期, 可以进行购买), 此时是需要-价格, 进行购买, 由于要最大利润, 对两次状态的结果取最大值
  • dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i])

2.如果处于"可交易"状态, 那么第i - 1天, 可能处于"可交易"状态(i - 1天之前就卖了, 第i天还没买, 等于啥也没干), 可能处于"冷冻期"状态(i - 1天卖了, 第i天还没买, 等于啥也没干), 由于要最大利润, 对两次状态的结果取最大值

  • dp[i][1] = max(dp[i - 1][1], dp[i - 1][2])

3.如果处于"冷冻期"状态, 那么第i - 1天, 可能处于"买入"状态(i - 1天买了, 第i天卖了), , 此时是需要+价格, 进行购买,

  • dp[i][2] =dp[i - 1][0] + price[i]
  1. 初始化
    只需对0位置进行初始化
    dp[0][0] 说明买了股票, 利润为-prices[0]
    dp[0][1] 说明可以买, 利润为0
    dp[0][2] 说明冷冻期, 利润为0
  2. 填表顺序
    从左往右 三个表一起填
  3. 返回值
    返回max(dp[n - 1][0], dp[n - 1][1], dp[n - 1][2])
class Solution {public int maxProfit(int[] prices) {int n = prices.length;int[][] dp = new int[n][3];dp[0][0] = -prices[0];for(int i = 1; i < n; i++){dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]);dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][2]);dp[i][2] =dp[i - 1][0] + prices[i];}return Math.max(Math.max(dp[n - 1][0], dp[n - 1][1]), dp[n - 1][2]);}
}

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

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

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到第i天位置时, 此时的最大利润
  2. 状态转移方程
    第i天位置时, 有两种情况
    1.可能处于"买入"状态
    那么i - 1 位置可能是"买入"状态(啥也不干), 可能是"可交易"状态(买股票)
    f[i] = max(f[i - 1], g[i - 1] - p[i])
    2.可能处于"可交易"状态
    那么i - 1 位置可能是"买入"状态(卖股票, 再加上手续费), 可能是"可交易"状态(啥也不干)
    g[i] = max(f[i - 1] + p[i] - fee, g[i - 1])
  3. 初始化
    f[0] = -p[0] g[0] = 0
  4. 填表顺序
    从左往右 两个表一起填
  5. 返回值
    max(g[n - 1], f[n - 1])
class Solution {public int maxProfit(int[] prices, int fee) {int n = prices.length;int[] f = new int[n];int[] g = new int[n];f[0] = -prices[0];for(int i = 1; i < n; i++){f[i] = Math.max(f[i - 1], g[i - 1] - prices[i]);g[i] = Math.max(f[i - 1] + prices[i] - fee, g[i - 1]);}return Math.max(g[n - 1], f[n - 1]);}
}

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

买卖股票的最佳时机III

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到第i天结束之后, 此时的最大利润
    第i天位置时, 有两种情况, "买入"状态 和 "可交易"状态, 但是还要记录交易次数, 所以我们要使用二维数组
  2. 状态转移方程
    1.第i天可能处于"买入"状态, 此时完成了j次交易, i为最大利润
    那么i - 1 位置可能是"买入"状态(啥也不干), 可能是"可交易"状态(买股票)
    f[i][j] = max(f[i - 1][j], g[i - 1][j] - p[i])
    2.第i天可能处于"可交易"状态, 此时完成了j次交易, i为最大利润
    那么i - 1 位置可能是"买入"状态(卖股票, 交易次数 + 1), 可能是"可交易"状态(啥也不干)
    g[i][j] = max(f[i - 1][j - 1] + p[i], g[i - 1][j])
  3. 初始化
    f需要初始化第一行, g需要初始化第一行第一列
    所以我们可以修改一下状态转移方程, 只初始化第一行即可
    g[i][j] = g[i - 1][j];
    if(j - 1 >= 0) max(f[i - 1][j - 1] + p[i], g[i][j])

f[0][0] = -p[0] 第0天不可能完成多笔交易, 所以第一行其余填-0x3f3f3f3f (INT_MIN的一半, 不初始化为INT_MIN, 防止溢出
g[0][0] = 0 第一行其余填-0x3f3f3f3f
4. 填表顺序
从左往右 从上往下 两个表一起填
5. 返回值
返回可交易表最后一行的最大值

class Solution {public int maxProfit(int[] prices) {int n = prices.length;int INF = 0x3f3f3f3f;int[][] f = new int[n][3];int[][] g = new int[n][3];for(int j = 0; j < 3; j++){f[0][j] = g[0][j] = -INF;}f[0][0] = -prices[0];g[0][0] = 0;for(int i = 1; i < n; i++){for(int j = 0; j < 3; j++){f[i][j] = Math.max(f[i - 1][j], g[i - 1][j] - prices[i]);g[i][j] = g[i - 1][j];if(j - 1 >= 0) g[i][j] = Math.max(g[i][j], f[i - 1][j - 1] + prices[i]);}}int ret = 0;for(int j = 0; j < 3; j++){ret = Math.max(ret, g[n - 1][j]);}return ret;}
}

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

买卖股票的最佳时机IV

  1. 状态表示
    根据经验 + 题目要求
    dp[i] 表示: 选择到第i天结束之后, 此时的最大利润
    第i天位置时, 有两种情况, "买入"状态 和 "可交易"状态, 但是还要记录交易次数, 所以我们要使用二维数组
  2. 状态转移方程
    1.第i天可能处于"买入"状态, 此时完成了j次交易, i为最大利润
    那么i - 1 位置可能是"买入"状态(啥也不干), 可能是"可交易"状态(买股票)
    f[i][j] = max(f[i - 1][j], g[i - 1][j] - p[i])
    2.第i天可能处于"可交易"状态, 此时完成了j次交易, i为最大利润
    那么i - 1 位置可能是"买入"状态(卖股票, 交易次数 + 1), 可能是"可交易"状态(啥也不干)
    g[i][j] = max(f[i - 1][j - 1] + p[i], g[i - 1][j])
  3. 初始化
    f需要初始化第一行, g需要初始化第一行第一列
    所以我们可以修改一下状态转移方程, 只初始化第一行即可
    g[i][j] = g[i - 1][j];
    if(j - 1 >= 0) max(f[i - 1][j - 1] + p[i], g[i][j])

f[0][0] = -p[0] 第0天不可能完成多笔交易, 所以第一行其余填-0x3f3f3f3f (INT_MIN的一半, 不初始化为INT_MIN, 防止溢出
g[0][0] = 0 第一行其余填-0x3f3f3f3f
4. 填表顺序
从左往右 从上往下 两个表一起填
5. 返回值
返回可交易表最后一行的最大值

class Solution {public int maxProfit(int k, int[] prices) {int n = prices.length;k = Math.min(k, n / 2);int INF = 0x3f3f3f3f;int[][] f = new int[n][k + 1];int[][] g = new int[n][k + 1];for(int j = 0; j <= k; j++){f[0][j] = g[0][j] = -INF;}f[0][0] = -prices[0];g[0][0] = 0;for(int i = 1; i < n; i++){for(int j = 0; j <= k; j++){f[i][j] = Math.max(f[i - 1][j], g[i - 1][j] - prices[i]);g[i][j] = g[i - 1][j];if(j - 1 >= 0) g[i][j] = Math.max(g[i][j], f[i - 1][j - 1] + prices[i]);}}int ret = 0;for(int j = 0; j <= k; j++){ret = Math.max(ret, g[n - 1][j]);}return ret;}
}
http://www.rdtb.cn/news/2833.html

相关文章:

  • 网站文章更新怎么做百度网站下拉排名
  • wordpress弹性搜索seo教学视频教程
  • 网站空间流量手机网站搜索优化
  • 男女做爰视频免费网站百度seo排名查询
  • 网站备案 多久seo建站优化推广
  • 网站建站卖首饰侵权沈阳seo优化新势力
  • 网站建设吗google play下载官方版
  • 怎么去投诉做网站的公司百度快照优化推广
  • 现在那个网站做视频最赚钱吗百度风云榜各年度小说排行榜
  • 服务器架构做网站惠东seo公司
  • 临沂做网站推广的公司有爱站网关键词工具
  • 重庆市门户网站制作百度推广客服电话
  • 网站关键字排名提升工具2023最近爆发的流感叫什么
  • 山东聊城做网站一个网站如何推广
  • 云网站系统网站建设技术解决方案
  • 婚纱网站页面设计网站seo快速优化
  • phpcms网站模版网络营销的常用工具
  • 做首饰网站网上电商平台开发
  • 程序员自己做网站怎么能来钱中国站长之家官网
  • 网站制作完成之后我们便进入了什么阶段最新国际军事动态
  • 手机建网站公司网络互联网推广
  • 如何创建一个公司网站广东省新闻
  • 进qq空间上面没有网站上海搜索关键词排名
  • 网站备案主体是cilimao磁力猫
  • 怎样查到一些做品牌包的网站竞价如何屏蔽恶意点击
  • 网页设计师需要学什么专业seo网络公司
  • 郑州网站推广优化公司如何创建个人网页
  • 网站制作眼seo外链专员
  • 网站索引页面新闻20条摘抄大全
  • 进一步加强政府网站建设百度用户服务中心官网电话