SP3943 MDOLLS - Nested Dolls
题意翻译
迪沃斯是世界上最著名的俄罗斯套娃收藏家:你知道吗?他真的有成千上万的套娃!不同大小的空心木娃娃,最小的娃娃装在第二大的娃娃里,而这个娃娃又装在下一个娃娃里,等等。有一天,他想知道是否有另一种方式来嵌套它们,这样他就能减少套套玩偶的数量?毕竟,那会使他的收藏更加华丽!他打开每个嵌套的娃娃,测量每个娃娃的宽度和高度。当且仅当w1 < w2且h1 < h2时,宽度为w1且高度为h1的娃娃才能与另一个宽度为w2且高度为h的娃娃相匹配。你能帮他从他的大量测量数据中计算出最小的嵌套娃娃数量吗?
输入格式
On the first line of input is a single positive integer 1 ≤ t ≤ 20 specifying
the number of test cases to follow. Each test case begins with a positive
integer 1 ≤ m ≤ 20000 on a line of itself telling the number of dolls
in the test case. Next follow 2m positive integers w1, h1,w2, h2, … ,wm,
hm, where wi is the width and hi is the height of doll number i.
1 ≤ wi, hi ≤ 10000 for all i.
SAMPLE INPUT
4
3
20 30 40 50 30 40
4
20 30 10 10 30 20 40 50
3
10 30 20 20 30 10
4
10 10 20 30 40 50 39 51
输出格式
For each test case there should be one line of output containing the minimum
number of nested dolls possible.
SAMPLE OUTPUT
1
2
3
2
思路
首先看到这个题,还是没有理解题意,在读几遍之后,发现这就是一个贪心的题,(通过一些题解,发现网上说这个题的解法与LIS类似,但思路完全不同,会在下篇详细介绍LIS)。
w升序,w相同时h降序排序后是可以贪心的,这里使用了动态维护表的二分算法,表里动态维护了每堆玩具中h的最大值(所以w相同时h要降序)。有
int cmp(Point a,Point b){
return a.w == b.w ? a.h > b.h : a.w < b.w;
//w相等时,按照h降序;否则,w不相等,按照w升序
}
题解
#include<bits/stdc++.h>
using namespace std;
const int N = 20005;
//定义结构体存储一个套娃的长和宽
struct Point{
int w,h;
}p[N];
int h[N];
int cmp(Point a,Point b){
return a.w == b.w ? a.h > b.h : a.w < b.w;
//w相等时,按照h降序;否则,w不相等,按照w升序
}
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
for(int i=0;i<n;i++){
cin >> p[i].w >> p[i].h;
}
sort(p,p+n,cmp);
/*for(int i =0;i<n;i++){
cout << p[i].w << " " << p[i].h << endl;
} */
int len = 0;
for(int i=0;i<n;i++){
int cur = p[i].h;
int left = 0;
int right = len;
while(left < right){
int mid = (left + right) / 2;
if(h[mid] >= cur) left = mid + 1;
else right = mid;
}
if(len == left)
len++;
h[left] = cur;
}
cout << len << endl;
}
return 0;
}
其中,以下的二分查找还是不太理解,
int len = 0;
for(int i=0;i<n;i++){
int cur = p[i].h;
int left = 0;
int right = len;
while(left < right){
int mid = (left + right) / 2;
if(h[mid] >= cur) left = mid + 1;
else right = mid;
}
if(len == left)
len++;
h[left] = cur;
}