信封问题(dp题)c++

这篇博客介绍了如何使用C++解决一个类似于俄罗斯套娃的信封问题。给定一组信封的宽度和高度,目标是找到最多能套在一起的信封数量。这个问题可以视为二维最长上升子序列问题。博客提供了输入输出格式、样例数据及AC代码。

小明在电视上看到《迪斯卡威》节目正在播放俄罗斯的套娃玩具,他突然想到可以用信封来模拟该玩具。小明手上有n个信封,其中第i个信封的宽度为wi, 高度为hi。信封套娃的规则是,当信封a的宽度wa比另一个信封b的宽度wb大,并且a的高度ha也比b的高度hb大时,则信封a就可以放进信封b里面,多个信封可以层层装入,如同俄罗斯套娃一样。注意,当给定信封的宽和高以后,信封不能旋转。

现请你计算,小明手上的这n个信封,最多能选取多少个信封组成一组“最多套娃信封”玩具。

输入格式

输入文件名:x.in

第一行n,表示信封的总个数。1<=n<=10000

接下来的n+1行中,每行两个整数表示第i个信封的宽wi和高hi。1<=wi,hi<=10000

输出格式

输出文件名:x.out

一个整数,表示“最多套娃信封”玩具包含的信封个数。

说明: 不允许旋转信封。

输入/输出例子1

输入:

4

5 4

6 4

6 7

2 3

输出:

3

样例解释

最多信封个数为3,组合为[2,3] [5,4] [6,7]

这是一个二维的最长上升子序列,也就是改版的一维子序列。

先给最长子序列代码:

#include<bits/stdc++.h>
using namespace std;
int n,num[100000],dp[200000];
void lis(){
    for(int i=0;i<n;i++){
        dp[i]=1;   //base
以下是两种使用 C++ 解决俄罗斯套娃信封问题的代码示例: ### 方法一:简单暴力的动态规划 ```cpp #include <vector> #include <algorithm> class Solution { public: int maxEnvelopes(std::vector<std::vector<int>>& envelopes) { if(envelopes.empty()) return 0; std::sort(envelopes.begin(), envelopes.end(), [](const std::vector<int> &a, const std::vector<int> &b){ return a[0] < b[0] || (a[0] == b[0] && a[1] < b[1]); }); // dp[i] 表示 i 之前的所有元素中能装进信封 i 的最大个数 std::vector<int> dp(envelopes.size(), 1); for(int i = 1; i < envelopes.size(); ++i){ for(int j = i - 1; j >= 0; --j){ if(envelopes[i][1] > envelopes[j][1] && envelopes[i][0] > envelopes[j][0]){ dp[i] = std::max(1 + dp[j], dp[i]); } } } return *std::max_element(dp.begin(), dp.end()); } }; ``` ### 方法二:优化的动态规划 ```cpp #include <vector> #include <algorithm> class Solution { public: int maxEnvelopes(std::vector<std::vector<int>>& envelopes) { if (envelopes.empty()) { return 0; } int n = envelopes.size(); std::sort(envelopes.begin(), envelopes.end(), [](const auto& e1, const auto& e2) { return e1[0] < e2[0] || (e1[0] == e2[0] && e1[1] > e2[1]); }); std::vector<int> f(n, 1); for (int i = 1; i < n; ++i) { for (int j = 0; j < i; ++j) { if (envelopes[j][1] < envelopes[i][1]) { f[i] = std::max(f[i], f[j] + 1); } } } return *std::max_element(f.begin(), f.end()); } }; ``` ### 调用示例 ```cpp #include <iostream> int main() { std::vector<std::vector<int>> envelopes = {{5,4},{6,4},{6,7},{2,3}}; Solution sol; int result = sol.maxEnvelopes(envelopes); std::cout << "最多能套娃的信封数量: " << result << std::endl; return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值