题解:P3845 [TJOI2007] 球赛

考虑不妨设每个 (x,y)(x,y) 都有 xyx \leq y,容易发现规定顺序没有影响。

考虑 (x1,y1)(x_1,y_1)(x2,y2)(x_2,y_2),什么时候可以比较。当且仅当 x1x2y1y2x_1 \leq x_2 \land y_1 \leq y_2,或者 x1x2y1y2x_1 \geq x_2 \land y_1 \geq y_2

注意到我们要求的其实是偏序集上的最小链覆盖,根据 Dilworth 定理知就等价于最长反链。

不妨考虑反链是 (x1,y1),(x2,y2),,(xk,yk)(x_1,y_1),(x_2,y_2),\cdots,(x_k,y_k),且 xx 已经不降排序了,那么容易发现对于任意 i<ji < j,都有 yi>yjy_i > y_j,于是将 xx 排序后求 yy 的最长下降子序列即可。

范围很小,O(n2)O(n^2) DP 即可。

注意 xx 相同时只能取一个 yy

代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <utility>
using namespace std;

const int N = 1005;

int n, x[N], y[N], t;
int ans;

pair<int, int> a[N];
int f[N];

int main()
{
	scanf("%d", &t);
	while (t--)
	{
		ans = 1;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d-%d", &x[i], &y[i]);
			if (x[i] > y[i]) swap(x[i], y[i]);
			a[i] = make_pair(x[i], y[i]);
		}
		sort(a + 1, a + n + 1);
		for (int i = 1; i <= n; i++)
		{
			f[i] = 1;
			for (int j = 1; j < i; j++)
			{
				if (a[j].second > a[i].second) f[i] = max(f[i], f[j] + 1);
			}
			ans = max(ans, f[i]);
		}
		printf("%d\n", ans);
	}
	return 0;
}
posted @   HappyBobb  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示