【CF4D Mysterious Present】题解

题目链接

题目

Peter decided to wish happy birthday to his friend from Australia and send him a card. To make his present more mysterious, he decided to make a chain. Chain here is such a sequence of envelopes A A A = { a1,a2,...,an a_{1},a_{2},...,a_{n} a1​,a2​,...,an​ }, where the width and the height of the i i i -th envelope is strictly higher than the width and the height of the (i−1) (i-1) (i−1) -th envelope respectively. Chain size is the number of envelopes in the chain.

Peter wants to make the chain of the maximum size from the envelopes he has, the chain should be such, that he'll be able to put a card into it. The card fits into the chain if its width and height is lower than the width and the height of the smallest envelope in the chain respectively. It's forbidden to turn the card and the envelopes.

Peter has very many envelopes and very little time, this hard task is entrusted to you.

给出一个限制 (w,h)(w,h)(w,h) 和 nnn 个物品的二维信息(wi,hi)(w_i,h_i)(wi​,hi​)

求物品二维都满足 wi>w,hi>hw_i>w,h_i>hwi​>w,hi​>h 的前提下的最长二维严格上升子序列以及其长度(wi>wi−1,hi>hi−1(w_i>w_{i-1},h_i > h_{i-1}(wi​>wi−1​,hi​>hi−1​ )

如果找不到任何一个物品满足条件 只需输出一行 0

思路

先排除掉不符合的,然后按x轴排序,接着按y轴做最长上升子序列即可。

上升子序列只需要打暴力的,什么二分单调队列树状数组优化都不用。

总结

这题本质上就是最长上升子序列模板,并不需要太多技巧。

这种题认真看题,打时认真点即可。

也可以顺手复习一下 \(O(n\log n)\) 方法。

Code

// Problem: CF4D Mysterious Present
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF4D
// Memory Limit: 62 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 5010
struct node
{
	int x, y, id; 
}a[N]; 
int n, m, i, j, k; 
int w, h, dp[N], pre[N]; 

bool cmp(node x, node y)
{
	if(x.x==y.x) return x.y<y.y; 
	return x.x<y.x; 
}

void dfs(int x)
{
	if(pre[x]) dfs(pre[x]); 
	printf("%lld ", a[x].id); 
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	n=read(); w=read(); h=read(); 
	for(i=1; i<=n; ++i)
	{
		a[i].x=read(); a[i].y=read(); 
		if((a[i].x<=w)||(a[i].y<=h)) continue; 
		// printf("0"); 
		a[++m].x=a[i].x; a[m].y=a[i].y; a[m].id=i; 
	}
	sort(a+1, a+(n=m)+1, cmp); 
	for(i=1, m=0; i<=n; ++i)
	{
		dp[i]=1; pre[i]=0; 
		for(j=1; j<=n; ++j)
			if(a[i].x>a[j].x&&a[i].y>a[j].y)
				if(dp[j]+1>dp[i])
					dp[i]=dp[j]+1, pre[i]=j; 
		if(dp[i]>m) m=dp[i], k=i; 
	}
	printf("%lld\n", m); 
	if(m) dfs(k); 
	return 0; 
}


posted @ 2021-12-24 19:02  zhangtingxi  阅读(83)  评论(0编辑  收藏  举报