2020牛客寒假算法基础集训营6 C题

汉诺塔

题目描述

现在你有 N 块矩形木板,第 i 块木板的尺寸是 Xi*Yi,你想用这些木板来玩汉诺塔的游戏。
我们知道玩汉诺塔游戏需要把若干木板按照上小下大的顺序堆叠在一起,但因为木板是矩形,所以有一个问题:
第 i 块木板能放在第 j 块木板上方当且仅当 Xi<Xj 且 Yi<Yj,于是你很可能没法把所有的木板按照一定的次序叠放起来。
你想把这些木板分为尽可能少的组,使得每组内的木板都能按照一定的次序叠放。
你需要给出任意一种合理的分组方案。
提醒:“任意”意味着你的答案不必和标准输出完全一致,只要正确即可。

输入描述:

第一行,一个正整数 N
接下来 N 行,每行两个正整数表示 Xi 和 Yi
对于所有的数据,1≤N≤100,000,1≤Xi,Yi≤N,Xi 互不相等且 Yi 互不相等

输出描述:

输出文件包含两行,第一行一个正整数,表示最少组数
第二行 N 个正整数,依次表示你的方案中每块木板分在了哪一组
组的编号必须是从 1 开始的连续整数


这道题用到了,Dilworth定理

其实知道了这个定理,这道题就会做了,还有个技巧是二分在求得最长递减子序列的长度时,把分组一起算了出来,当一个元素可以被另一个元素在其位置取代时,这些元素就被分在了同一个组;

代码:

#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
#define inf 0x3f3f3f3f
//ios::sync_with_stdio(false);
using namespace std;
const int N=100100;
const int M=1000100;
const ll mod=998244353;
struct Node{
	int x,y;
	int post;
}a[N];
bool cmp(Node p,Node q){
	return p.x<q.x;
}
int ans[N];
int sta[N];
int main(){
	ios::sync_with_stdio(false);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y;
		a[i].post=i;
	} 
	sort(a+1,a+1+n,cmp);
	int m=0;
	for(int i=1;i<=n;i++){
		int l=1,r=m;
		while(l<=r){
			int d=(l+r)>>1;
			if(sta[d]<a[i].y) r=d-1;
			else l=d+1;
		}
		sta[l]=a[i].y;
		if(l>m) m=l;
		ans[a[i].post]=l;
	}
	cout<<m<<endl;
	for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值