本题可通过巧妙的处理将问题转化为最长递增子序列问题,将先信封的长边(li)由小到大排序,在同等长边(li)的情况下按宽边(wi)由大到小排序。之后将排序后的宽边(wi)按最长递增子序列问题处理。
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int vecSize;
scanf("%d", &vecSize);
vector<vector<int>> veci = vector(vecSize, vector<int>(2));
for(int i = 0; i < vecSize; ++i)
{
int l;
int w;
scanf("%d%d", &l, &w);
veci[i][0] = l;
veci[i][1] = w;
}
sort(veci.begin(), veci.end(), [](vector<int> &a, vector<int> &b){return a[0] == b[0] ? a[1] > b[1] : a[0] < b[0];}); //长边按从小到大排序,宽边从大到小排序
vector<int> load(vecSize);
for(int i = 0; i < vecSize; ++i)
load[i] = veci[i][1];
vector<int> pile(vecSize);
int piles = 0;
for(int i = 0; i < vecSize; ++i)
{
int left = 0;
int right = piles;
int pocker = load[i];
while(left < right)
{
int mid = left + (right - left) / 2;
if(pile[mid] > pocker)
right = mid;
else if(pile[mid] < pocker)
left = mid + 1;
else
right = mid;
}
if(left == piles) ++piles;
pile[left] = pocker;
}
printf("%d", piles);
return 0;
}