二分查找 + 贪心

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;
	}	
二分贪心算法和浙江工业大学之间似乎没有直接的关联。二分贪心算法是一种综合了二分和贪心思想的算法,用于在解决问题时对数据进行二分划分,并在每一步选择中采取最优的贪心策略。而浙江工业大学是一所位于中国浙江省的工科大学。 引用和中提到的贪心算法是一种在问题求解中每一步都选择最优的策略,但得到的结果不一定是最优解,但是通常是相对近似最优解的结果。这种算法在某种意义上是局部最优解。 引用中提到的Dijkstra算法是一种基于贪心和广度优先搜索的算法,用于求解图中一个点到其他所有点的最短路径。该算法的时间复杂度为O(n^2)。 从以上内容来看,二分贪心算法和浙江工业大学之间并没有明显的联系。可能是问题描述不完整或者存在其他相关信息,导致无法直接回答与贪心算法和浙江工业大学有关的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法...](https://blog.csdn.net/lonelysnowman/article/details/127493659)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [6.二分+贪心](https://blog.csdn.net/qq_52008247/article/details/119151264)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值