首页 > 编程语言 >一个算法题目的探索

一个算法题目的探索

时间:2025-01-14 20:11:59浏览次数:1  
标签:题目 探索 end 算法 区间 quad type 节点 dp

首先提出一个简单的问题,之后在此基础上一步步进行拓展,整体上从易到难,逐渐深入。

问题一

给定 \(n\) 个区间 \([l_i,r_i]\) ,选出至多\(2\)个两两不重叠的区间 \([start_i, end_i]\),每个区间由 \([l_x, r_y]\) 组成( \(y\ge x\)),最大化 \(\sum (end_i - start_i)\)

分析

将\(n\)个区间放到数轴上可以看作\(2n\)个点,每个节点有相应的类型(左或右)、值的大小,同时由于限制选取的每个区间为 \([l_x,r_y]\),为方便之后的处理可以按照给定区间的顺序将2n个节点进行排序。

要选择至多两个区间,可以通过选取两个区间的分割点,得到分割点左右区间收益之和,取最大值,具体实现可以维护两个长度为\(2n\)的数组\(MaxLeft\)和\(MaxRight\),分别记录当前节点左区间和右区间可以取到的最大值,之后遍历所有\(2n\)个节点即可,时间复杂度为 \(O(n)\).

对于两个数组的维护,这里以MaxLeft数组为例说明,假设当前节点类型为左边界,那么就更新 \(MaxLeft [i]=MaxLeft [i-1]\),同时更新 当前最小的 \(MinL\) ;当前节点若为右边界,则更新为当前节点的值减去\(MinL\)。

\[MaxLeft[i]=\left\{ \begin{array}[ll]\ MaxLeft [i-1]\quad \text{if}\ type_i= l \\ value_i-MinL\quad\ \text{if}\ type_i=r \end{array} \right. \]

同理 \(MaxRight\) 的更新规则如下:

\[MaxRight[i]=\left\{ \begin{array}[ll]\ MaxRight [i+1]\quad \text{if}\ type_i= r \\ MaxR-value_i\quad\ \text{if}\ type_i=l \end{array} \right. \]

之后遍历所有 \(2n\) 个节点,\(Result= Maxmize_i\quad MaxRight[i]+MaxLeft[i]\)

问题二

给定 \(n\) 个区间 \([l_i,r_i]\) ,选出至多\(k\)个两两不重叠的区间 \([start_i, end_i]\),每个区间由 \([l_x, r_y]\) 组成( \(y\ge x\)),最大化 \(\sum (end_i - start_i)\)

分析

与问题一唯一的区别是将区间的选择由\(2\)个变为了\(k\)个,这时便不能简单的枚举分割点了。这时的问题便需要使用动态规划的方法。

考虑 \(dp[i][j]\) 表示在选取前 \(i\) 个节点并选择 \(j\) 个区间得到的最大值,那么最终的结果为 \(dp[2n][k]\)

对于边界值 \(dp[i][0]=dp[0][j]=0, \forall i\in[1,2n],j\in[1,k]\).

之后考虑如何进行更新,如果该节点类型为左边界节点,那么在加入该节点后一定不会发生区间选择的变化,\(dp[i][j]=max(dp[i][j],dp[i-1][j])\) ; 如果该节点类型为右边界节点,假设该节点加入后不会发生区间选择的变化,那么\(dp[i][j]=max(dp[i][j],dp[i-1][j])\) ,如果会发生区间选择的变化,那么选择的第 \(j\) 个区间,便是当前节点与之前的某个左边界节点形成的一个新区间,通过遍历之前的左边界节点更新: $dp[i][j]=max(dp[i][j],dp[s-1][j-1]+value_i-value_s),\forall s\in[1,i],type_s=l $

因此最终的递推方程为:

\[dp[i][j]=\left\{ \begin{array}[ll]\ \begin{split} max(dp[i][j],dp[i][j-1]) \quad \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad \text{if}\ type_i=l\\ max(dp[i][j],dp[i][j-1],dp[s-1][j-1]+value_i-value_s)\quad \text{if}\ type_i=r \end{split} \end{array} \right. \]

需要注意的是 \(s\in[1,i]\) 并且 \(\text{type}_i = l\) 。

最终的时间复杂度为 \(O(n^2k)\) ,这里可以通过某些数据结构(树/队列)来存储查询 \(dp[s-1][j-1]-value_s\) 的最大值,消除循环查询最大值,实现 \(log_n\) 的查询,时间复杂度可以优化到 \(O(nklog_n)\)

问题三

(1)给定一个数组,它的第 \(i\) 个元素是一支给定的股票在第 \(i\) 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

(2)给你一个整数数组 \(prices\) 和一个整数 \(k\) ,其中 \(prices[i]\) 是某支给定的股票在第 \(i\) 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 \(k\) 笔交易。也就是说,你最多可以买 \(k\) 次,卖 \(k\) 次。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

分析

上面两个问题是 LeetCode 中的两道题,题目链接如下:

买卖股票的最佳时机III买卖股票的最佳时机IV

仔细分析可以发现,买一支股票然后卖掉,如果想要得到最大收益,肯定要在低价时买入,在高价时卖出,而从低价到高价期间的值是没什么意义的;同时,在一支股票后面的值如果比前面的值要小(\(prices[i+1]\le prices[i]\)),那么购买前面的股票是没什么意义的,一定不是最优的。所以,对于给定的prices数组,按照这两个原则进行处理后,便得到了m对数组 \((l_i,r_i)\),并且 \(l_i<r_i,r_i>l_{i+1}\),这样这两个问题便转化为了前面的问题一和问题二,问题解决。

标签:题目,探索,end,算法,区间,quad,type,节点,dp
From: https://www.cnblogs.com/sunmk/p/18671486

相关文章

  • 【优先算法】思还故里闾,欲归道无因 - 前缀和
    本篇博客给大家带来的是前缀和算法的知识点,也是一样通过OJ题理解,掌握,应用该算法.......
  • 令人惊艳的算法分享!
    惊艳的算法引言你是否曾想过,是什么让计算机能够如此快速而高效地处理信息?这背后恰恰是算法的功劳。作为计算机科学的基石,算法不仅是解决问题的工具,更是推动技术进步的动力。在这篇文章中,我们将探讨几种经典和新兴的算法,揭示它们是如何颠覆我们对计算的认识并激发创新的。......
  • 排序算法专题总结
    分治基础-二分查找:二分查找是一种高效的查找算法先找到数组的中间位置mid,判断(1)如果要找的数x==a[mid]找到了,mid就是位置(2)如果要找的教x>a[mid],说明要找的数在后一半,递归在后一半找(3)如果要找的数x<a[mid],说明要找的数在前一半,递归在前一半找在下标为left~right之间的......
  • 探索AI与鸿蒙开发新领域:从《星火AI使用指南》到《鸿蒙应用开发宝典》
    探索AI与鸿蒙开发前言AI智能化办公讯飞星火AI使用方法与技巧从入门到精通内容简介获取方式鸿蒙HarmonyOS应用开发从入门到精通内容简介获取方式总结前言在数字化的今天,科技的飞速发展让我们每天都在面临新的挑战和机遇。尤其是对于那些追求效率、寻求突破的职场人......
  • 随机生成20以内加减法运算题目
    <?phpfunctiongenerateMathProblem(){//随机选择加法或减法$operation=rand(0,1)?'+':'-';//生成两个0到20之间的随机数$num1=rand(0,20);$num2=rand(0,20);//计算结果,注意处理减法可能导致负数的情况if($operation=......
  • 【一看就会】路径规划算法【一】——广度优先,深度优先,Dijkstra、A*、D*
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、输入输出1.输入环境约束条件目标其他2.输出二、广度优先搜索——BFS三、深度优先搜索——DFS四、Dijkstra五、A*六、D*1.初始路径规划(环境未变化)2.环境变化3.动态调整1.受影响节点标记2......
  • 算法-高精度问题(带图详细解读~)
    今天来分享四道大数运算的模板题.目录1.大数相加2.大数相减3.大数相乘4.大数相除1.大数相加题目链接:LINK基本思路:存入数组,模拟运算.逆序字符串补零操作依次取数据,依次相加3-1加:(t-ret=s1[i]+s2[i]+carry)%10;3-2进:(t-ret=s1[i]+......
  • 「Note」欧几里得算法全家桶
    一,欧几里得算法1.内容\(\gcd(a,b)=\gcd(b,a\modb)\)2.证明先假设\(a>b\),\(a=bx+y\),其中\(x=\lfloor\frac{a}{b}\rfloor,0\ley\ltb\)。也就是\(b\)除以\(a\)等于\(x\)余\(y\)。原命题就是\(\gcd(a,b)=\gcd(y,b)\)。由\(a=bx......
  • BI简史:穿越数据迷雾的探索之旅(下)—BI智能的开端
    “复杂社会的一项重要特征,就是站在一场波澜壮阔的革命的最初阶段,你基本分辨不清真正重要的力量是什么,也看不透最终赢得胜利的那股势力将从何处冒头。”——张笑宇,《产业与文明:复杂社会的兴衰》在21世纪的头20年,科技的浪潮如洪水般席卷而来,带来了无数丰硕的成果.上篇《BI简史......
  • 【轻松掌握数据结构与算法】哈希(Hashing)
    什么是哈希?哈希是一种将任意长度的数据转换为固定长度的数据的技术。这个固定长度的数据通常被称为哈希值或哈希码。哈希函数是实现这一转换的关键,它接受任意长度的输入,并产生一个固定长度的输出。为什么使用哈希?哈希的主要用途之一是快速查找数据。通过哈希函数,我们可以将......