leetcode Russian Doll Envelopes

题目要求用大信封装小信封,问最多可以这样嵌套多少个。
最简单的做法就是动态规划,01背包问题,把数组排序,先按第一个元素排序,再按第二个元素排序。dp[i]表示以i作为最大信封,0-i个信封,最多装多少个。问题没有后续性,时间复杂度O(n^2)
然而如果我们对第二个元素排序时按从大到小排序,这时候有个神奇的东西诞生了。
问题等价于求LIS(最长上升子序列的长度),倒序第二个元素是为了排除第一个元素相同,第二个元素算了几个进去。
于是我们用单调栈就可以解决啦,dp[i]表示长度为i+1的子序列,i这个元素最小是多少。注意单调栈中的结果不一定是最后最长长度的解哦。
bool cmp( const pair<int, int> &a, const pair<int, int> &b )
{
if( a.first == b.first )return a.second > b.second;
return a.first < b.first;
}




class Solution {
public:
int maxEnvelopes(vector<pair<int, int>>& envelopes) {
int n = envelopes.size();
if(n==0)return 0;
vector<int> dp(n,0);
int top = 0;
sort(envelopes.begin(), envelopes.end(), cmp );
for( auto tInfo: envelopes )
{
if( top == 0 )
{
dp[top++] = tInfo.second;
continue;
}




if( dp[top - 1] < tInfo.second )
{
dp[top++] =tInfo.second;
continue;
}




int low = 0, high = top - 1;
while( low < high )
{
int mid = low + ((high - low) >> 1);
if( dp[mid] < tInfo.second )low = mid + 1;
else
{
high = mid;
}
}
dp[low] = tInfo.second;
}
return top;
}
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值