题目描述
解题思路
首先将信封按照从小到大的顺序进行排序:先按照信封的宽a排序,如果宽a相同则按照长b排序。
bool cmp(pair<int, int> x, pair<int, int> y)
{
if(x.first != y.first){
return x.first < y.first;
}else{
return x.second < y.second;
}
}
...
// vector<pair<int, int>> letters;
sort(letters.begin(), letters.end(), cmp);
然后求排序后letters数组的最长严格上升子序列。需要注意的是:之前在嘴上上升子序列中,将当前元素arr[i]续到之前的某一个dp[k]之后的判断条件是arr[k] < arr[i]
,现在对元素大小的定义发生了变化,判断条件应该是letters[k].first < letters[i].first && letters[k].second < letters[i].second
。
int solve(){
...
vector<int> dp(n); // dp[i]: 以letters[i]结尾的最长上升子序列的长度
// init
dp[0] = 1;
int max_dp = dp[0];
// bottom-up
for(int i=1; i<n; i++){
dp[i] = 1;
for(int k=0; k<i; k++){
if(letters[k].first < letters[i].first
&& letters[k].second < letters[i].second){
dp[i] = max(dp[i], dp[k]+1);
}
}
max_dp = max(dp[i], max_dp);
}
return max_dp;
}
C++代码实现
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int n;
vector<pair<int, int>> letters;
void input(){
cin >> n;
pair<int, int> temp;
for(int i=0; i<n; i++){
cin >> temp.first >> temp.second;
letters.push_back(temp);
}
}
bool cmp(pair<int, int> x, pair<int, int> y)
{
if(x.first != y.first){
return x.first < y.first;
}else{
return x.second < y.second;
}
}
int solve(){
sort(letters.begin(), letters.end(), cmp);
vector<int> dp(n); // dp[i]: 以letters[i]结尾的最长上升子序列的长度
// init
dp[0] = 1;
int max_dp = dp[0];
// bottom-up
for(int i=1; i<n; i++){
dp[i] = 1;
for(int k=0; k<i; k++){
if(letters[k].first < letters[i].first
&& letters[k].second < letters[i].second){
dp[i] = max(dp[i], dp[k]+1);
}
}
max_dp = max(dp[i], max_dp);
}
return max_dp;
}
int main() {
input();
cout << solve();
}