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

2023-08-01力扣今日二题-Hard-DPLIS优先队列-好题

链接:

354. 俄罗斯套娃信封问题

题意:

一个信封有长宽,如果一个信封的长宽均严格大于另一个信封,那么大的这个信封可以装下小的这个信封

求最多能套娃几个信封

解:

类似普通的最长上升子序列,但是信封有两个数据,第一时间想到的是优先队列排序,但是我们发现这两个数据并没有优先级,也不能通过加减乘除之类的操作制造一个新的关键数据

我们看一下正常最长上升子序列的解法动态规划的LIS算法,它的DP[i-1](下标初始为0,使用后置++的方法赋值和保存长度)表示长度i的上升子序列最后一位的最小值

主要过程我将他分为两步:更新&扩展,更新是指我的数值并不足以扩展出更长的上升子序列,但是我可以使某个长度的上升子序列最后一位更小(结尾越小理论越长);扩展则是指我的数值可以完成扩展,那我就增加DP计数并保存这个数值。

那假如我们用w升序,h在此基础上升序,那么对于w来说,后进的永远大于等于先进的,这是部分符合的,所以如果我们遇到w5h15,w10h10,w15h20,完全可以用w10h10更新w5h15(w10也能满足w15,优先选择h最小的);但是如果存在同w下h的升序,例如w5h15,w10h10,w10h20,我们就能发现更新完以后,w10h20并不能接在w10h10后面,反而应该接在w5h15后面。

我们分析这个错误就可以发现,如果w升序排序,我们就可以用大的w小的h更新原先小的w大的h,如果同w情况下h升序排序,更新会先进行,先更新的后果/错误就是如果被更新的是目前求出来的最长子序列最后一位的最小值,那么本来能扩展长度的数据就会因为这个更新后的w和自身相同无法完成扩展,或者更新后的h小于原先的h进行错误扩展(看你怎么判断扩展的=-=)(当然也会导致其他更新的错误)

先更新后扩展不行,能不能先扩展后更新,实际上这就是答案:让w升序的情况下h降序,这样同w的情况下大的h就会先进行处理。

在处理一组新的w之前,我们已知数组里的old-w都小于这个new-w,那么如果new-w的h大于最后一位,就可以进行扩展,然后再遍历new-w中h降序的其他数据,来更新DP数组;我们能确保更新并不会导致已经求出的最长子序列长度变短,同时数组里只包含new-w和小于new-w的old-w;在条件w1>=w2&&h1<h2下,我们可知用w1h1更新w2h2将会是合法的。

实际代码:

#include<bits/stdc++.h>
using namespace std;
struct cmp
{bool operator() (const pair<int,int> &A,const pair<int,int> &B){if(A.first==B.first) return A.second<B.second;else return A.first>B.first;}
};
int maxEnvelopes(vector<vector<int>>& envelopes)
{int lg=envelopes.size(),now=0;vector<int>dp(lg); priority_queue<pair<int,int>,vector<pair<int,int>>,cmp>pq;for(const auto &envelope:envelopes) pq.push({envelope[0],envelope[1]});while(!pq.empty()){pair<int,int>temp=pq.top();pq.pop();if(now==0) dp[now++]=temp.second;else{if(temp.second>dp[now-1]) dp[now++]=temp.second;else{auto upper=lower_bound(dp.begin(),dp.begin()+now,temp.second);if(upper==dp.begin()+now||upper==dp.end()) continue;//没找到*upper=min(*upper,temp.second);}}}return now;
}
int main()
{vector<vector<int>> envelopes;int n;cin>>n;for(int i=0;i<n;i++){int a,b;cin>>a>>b;envelopes.push_back({a,b}); }int ans=maxEnvelopes(envelopes);cout<<ans<<endl;return 0;
}

限制:

  • 1 <= envelopes.length <= 105
  • envelopes[i].length == 2
  • 1 <= wi, hi <= 105
http://www.lryc.cn/news/107433.html

相关文章:

  • 并发 如何创建线程 多线程
  • 亚马逊鲲鹏系统是怎么引流的?
  • 第五章 Git
  • 无涯教程-Lua - 变量声明
  • vue3学习-组件基础、深入组件
  • 原型链污染分析
  • RF PCB的9条改进型建议
  • 网络安全(黑客)自学就业
  • uni-app选择器( uni-data-picker)选择任意级别
  • 网络入侵探测器Pi.Alert
  • Flask项目打包为exe(附带项目资源,静态文件)
  • 无代码开发(BIP旗舰版-YonBuilder)
  • 誉天程序员-瀑布模型-敏捷开发模型-DevOps模型比较
  • flutter:占位视图(骨架屏、shimmer)
  • 【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 4
  • python-网络爬虫.BS4
  • C# 开发规范
  • 【uniapp 样式】使用setStorageSync存储历史搜索记录
  • git remote add origin详解
  • 附录1-将uni-app运行到微信开发者工具
  • 【LeetCode】根据二叉树创建字符串
  • 【图论】强连通分量
  • 网络:VRP介绍
  • iOS - 解压ipa包中的Assert.car文件
  • 【Jmeter】配置不同业务请求比例,应对综合场景压测
  • TCP拥塞控制详解 | 1. 概述
  • 使用IPSEC VPN 在有防火墙的场景和有NAT转换的场景下实现隧道通信实验
  • Go和Java实现适配器模式
  • 接口相似数据结构复用率高?Apipost这招搞定!
  • 【零基础学Rust | 基础系列 | Hello, Rust】编写并运行第一个Rust程序