从零学算法2830

2830 .给你一个整数 n 表示数轴上的房屋数量,编号从 0 到 n - 1 。

另给你一个二维整数数组 offers ,其中 offersi = starti, endi, goldi 表示第 i 个买家想要以 goldi 枚金币的价格购买从 starti 到 endi 的所有房屋。

作为一名销售,你需要有策略地选择并销售房屋使自己的收入最大化。

返回你可以赚取的金币的最大数目。

注意 同一所房屋不能卖给不同的买家,并且允许保留一些房屋不进行出售。

示例 1:

输入:n = 5, offers = \[0,0,1,0,2,2,1,3,2]

输出:3

解释:

有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。

将位于 0,0 范围内的房屋以 1 金币的价格出售给第 1 位买家,并将位于 1,3 范围内的房屋以 2 金币的价格出售给第 3 位买家。

可以证明我们最多只能获得 3 枚金币。

示例 2:

输入:n = 5, offers = \[0,0,1,0,2,10,1,3,2]

输出:10

解释:有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。

将位于 0,2 范围内的房屋以 10 金币的价格出售给第 2 位买家。

可以证明我们最多只能获得 10 枚金币。

  • 老实说,我想过动态规划,也想过这个数组可能需要排序,就是没想到需要排序后动态规划。按我的想法,动态规划状态定义我只能想到 f(x) 为拥有房屋的最大编号为 x 时的最大利润,但我想不到状态转移方程,因为卖家可能是买一片区域的房子,所以就感觉如果房屋编号为 x-1 的房子如果售卖,编号为 x 的我都不确定他是不是在之前也被卖掉了。
  • 进入正题,状态定义我是想对的,但是为了能够状态转移,就需要对房屋购买数组按照购买的房屋最大编号进行排序,这样在房屋编号增加时,我们也能相对应的把可能的购买可能性计算进来。换言之,就是当我们 dp 往后递推,增加了房屋编号为 x 的房屋时,我们就需要看购买数组是否有买 x 房子的交易,有的话就需要考虑新增交易对 dpx 的影响。(为什么不是按照购买房屋最小编号排序,因为你在 dp 过程中增加编号 x 的房屋时,你只能根据购买房屋最大编号来判断这个购买是否对你的 dpx 有影响)所以当房屋编号增加,但是没人买这个房子时,很明显 dpx = dpx-1,而如果有人要买,如果你不卖当然还是 dpx-1,如果你卖给这个人,那么比如他要买的是 2-4 的房子,那么你最多只能卖到编号为 1 的房子,然后你的最大利润就是 dp1+他的购买金额,即此时 x=offer[k][1], dp[x] = dp[offer[k][0]-1]+offer[k][2],然后取卖或不卖的最大值即可。由于不一定就一个买家买,所以是不断移动 k,直到 offer[k][1] != x',在此期间要不断 max,那么就让 dpx 初始值为 dpx-1,然后在遍历 k 时不断 max。
java 复制代码
  public int maximizeTheProfit(int n, List<List<Integer>> offers) {
      int[] dp = new int[n+1];
      offers = offers.stream().sorted((l1,l2)->l1.get(1)-l2.get(1)).collect(Collectors.toList());
      // 由于购买第 1 间房子时购买数组显示的是购买 0 号房子
      // 然后 dp 时就会有 dp[0-1]+购买金额,我们的数组直接越界了
      // 所以就让 dp[1] 为拥有房屋最大编号为 1 时的最大利润
      // 所以提前把购买数组的购买房屋编号都加 1
      for(List<Integer> l:offers){
          l.set(0,l.get(0)+1);
          l.set(1,l.get(1)+1);
      }
      // j:遍历购买数组
      int j=0,m=offers.size();
      // i:遍历房屋编号
      for(int i=1;i<n+1;i++){
      	// 初始为不卖
          dp[i]=dp[i-1];
          // 如果有人买房屋编号为 i 的,就遍历购买数组
          // 直到别人要购买房屋的最大编号不等于 i,看看哪种方案利润最大
          while(j<m && offers.get(j).get(1) == i){
              int temp = dp[offers.get(j).get(0)-1] + offers.get(j).get(2);
              dp[i] = Math.max(dp[i],temp);
              j++;
          }
      }
      return dp[n];
  }
相关推荐
康实训6 分钟前
老年人能力评估实训室核心实训环节解析
人工智能·算法·实训室·实训室建设
强哥聊算力5 小时前
《算力江湖·英伟达传奇》第七集:ChatGPT出现前夜,英伟达发生了什么?
服务器·人工智能·算法·ai·chatgpt·gpu算力
Navigator_Z9 小时前
LeetCode //C - 1289. Minimum Falling Path Sum II
c语言·算法·leetcode
CCblandy9 小时前
令牌桶在 0.9 倍负载超发 19%、固定窗口边界放行 20 个:四种限流算法同构实测
后端·python·算法·性能优化·架构
YangYang9YangYan11 小时前
2027供应链计划校招:数学与应用数学专业如何把预测模型讲成业务决策?
人工智能·sql·算法
jsjzsl211 小时前
递归自改进系统(RSI)的本质是自发对称破缺:智能爆炸有界—— AI研发切记盲目投入
人工智能·python·算法
程序员清风11 小时前
最短路径算法:BFS、Dijkstra 与 Floyd
java·算法·宽度优先
梦帮科技11 小时前
Kali Linux Scapy 畸形报文构造学——深度解剖非法 TCP Flags 与反常序列号
linux·爬虫·神经网络·算法·数学建模·系统架构·模拟退火算法
171320330计算机毕设编程12 小时前
计算机毕业设计 基于YOLO改进算法的车辆特征识别系统设计与实现--lw
java·大数据·python·sql·算法