【题解】CF463D:Gargari and Permutations

本文介绍了一种使用DAG拓扑DP算法解决特定问题的方法。通过枚举x,y,建立DAG图并进行拓扑排序,最终通过DP算法找到最长路径。代码示例展示了如何实现这一算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题传送门
确实是一道不错的题目
发现k特别小
可以先 O ( n 2 ) O(n^2) O(n2)枚举 x , y x,y x,y,若 x x x在每个数列中都在 y y y前面,那么 x x x就可以向 y y y连一条边,这样建图建好以后整个图是一个 D A G DAG DAG,跑一个拓扑DP就好了
Code:

#include <bits/stdc++.h>
#define maxn 1000010
#define _ 0
using namespace std;
struct Edge{
	int to, next;
}edge[maxn << 1];
int num, head[maxn], n, k, pos[1010][6], in[maxn], dp[maxn];
queue <int> q;

inline int read(){
	int s = 0, w = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
	return s * w;
}

void addedge(int x, int y){ edge[++num] = (Edge){y, head[x]}, head[x] = num; }

int main(){
	n = read(), k = read();
	for (int i = 1; i <= k; ++i)
		for (int j = 1; j <= n; ++j) pos[read()][i] = j;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if (i != j){
				int flag = 1;
				for (int l = 1; l <= k; ++l)
					if (pos[i][l] > pos[j][l]){ flag = 0; break; }
				if (flag){
					++in[j]; addedge(i, j);
				}
			}
	for (int i = 1; i <= n; ++i)
		if (!in[i]) q.push(i), dp[i] = 1;
	while (!q.empty()){
		int u = q.front(); q.pop();
		for (int i = head[u]; i; i = edge[i].next){
			int v = edge[i].to;
			if (dp[v] < dp[u] + 1) dp[v] = dp[u] + 1;
			if (!(--in[v])) q.push(v);
		}
	}
	int ans = 0;
	for (int i = 1; i <= n; ++i) ans = max(ans, dp[i]);
	printf("%d\n", ans);
	return 0 ^ _ ^ 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值