Skip to Content

Substring

Editorial oficial 

Explicación

Definamos dp[i][j]\texttt{dp}[i][j] como la frecuencia máxima del carácter jj para el nodo ii. Luego, ordenamos los nodos topológicamente para hacer programación dinámica sobre el DAG. Nuestra transición es simple:

dp[i][j]=maxdp[k][j]:kadj[i] \texttt{dp}[i][j] = \max \texttt{dp}[k][j] : k \in \texttt{adj}[i]

mientras también incrementamos dp[i][l]\texttt{dp}[i][l] para el nodo actual ii donde ll representa sis_i, ya que podemos recoger una más de esta letra en nuestro camino.

Implementación

Complejidad temporal: O(N+M)\mathcal{O}(N + M)

#include <bits/stdc++.h> using namespace std; int main() { int n, m; cin >> n >> m; string a; cin >> a; vector<vector<int>> adj(n); vector<int> in_degree(n); for (int i = 0; i < m; i++) { int a, b; cin >> a >> b; a--; b--; in_degree[b]++; adj[a].push_back(b); } queue<int> queue; // dp[i][j] is the frequency of letter j when we are at node i. vector<vector<int>> dp(n, vector<int>(26)); for (int i = 0; i < n; i++) { if (in_degree[i] == 0) { queue.push(i); dp[i][a[i] - 'a']++; } } // Run topological sort. int size = 0; while (size < n && queue.size() > 0) { int cur = queue.front(); queue.pop(); for (int next : adj[cur]) { for (int j = 0; j < 26; j++) { // Update the frequency with the next occurrence. if (j == (a[next] - 'a')) { dp[next][j] = max(dp[cur][j] + 1, dp[next][j]); } else { dp[next][j] = max(dp[cur][j], dp[next][j]); } } // Add the next node to the queue. if (--in_degree[next] == 0) { queue.push(next); } } size++; } // No answer. if (size < n) { cout << -1 << endl; return 0; } // Find the maximum frequency across all nodes and letters. int ans = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < 26; j++) { ans = max(ans, dp[i][j]); } } cout << ans << endl; }
import java.io.*; import java.util.*; public class Substring { // CodeSnip{Kattio} public static void main(String[] args) throws IOException { Kattio io = new Kattio(); int N = io.nextInt(); int M = io.nextInt(); char[] A = io.next().toCharArray(); ArrayList<Integer>[] adj = new ArrayList[N]; for (int i = 0; i < N; i++) { adj[i] = new ArrayList<>(); } int inDegree[] = new int[N]; for (int i = 0; i < M; i++) { int a = io.nextInt() - 1; int b = io.nextInt() - 1; inDegree[b]++; adj[a].add(b); } Queue<Integer> queue = new LinkedList<>(); // dp[i][j] is the frequency of letter j when we are at node i int dp[][] = new int[N][26]; for (int i = 0; i < N; i++) { if (inDegree[i] == 0) { // enqueue the node queue.add(i); dp[i][A[i] - 'a']++; } } // topological sort int size = 0; while (size < N && queue.size() > 0) { int cur = queue.poll(); for (int next : adj[cur]) { for (int j = 0; j < 26; j++) { // update the frequency with the next occurrence if (j == (A[next] - 'a')) { dp[next][j] = Math.max(dp[cur][j] + 1, dp[next][j]); } else { dp[next][j] = Math.max(dp[cur][j], dp[next][j]); } } // add the next node to the queue if (--inDegree[next] == 0) { queue.add(next); } } size++; } // no answer if (size < N) { System.out.println(-1); return; } // find the maximum frequency across all nodes and letters int ans = 0; for (int i = 0; i < dp.length; i++) { for (int j = 0; j < dp[i].length; j++) { ans = Math.max(dp[i][j], ans); } } System.out.println(ans); } }
from collections import deque n, m = map(int, input().split()) a = input() adj = [[] for _ in range(n)] in_degree = [0] * n for _ in range(m): x, y = map(int, input().split()) x -= 1 y -= 1 in_degree[y] += 1 adj[x].append(y) queue = deque() # dp[i][j] is the frequency of letter j when we are at node i. dp = [[0] * 26 for _ in range(n)] for i in range(n): if in_degree[i] == 0: queue.append(i) dp[i][ord(a[i]) - ord("a")] += 1 # Run topological sort. size = 0 while size < n and len(queue) > 0: cur = queue.popleft() for nxt in adj[cur]: for j in range(26): # Update the frequency with the next occurrence. if j == ord(a[nxt]) - ord("a"): dp[nxt][j] = max(dp[cur][j] + 1, dp[nxt][j]) else: dp[nxt][j] = max(dp[cur][j], dp[nxt][j]) # Add the next node to the queue. in_degree[nxt] -= 1 if in_degree[nxt] == 0: queue.append(nxt) size += 1 # No answer. if size < n: print(-1) else: # Find the maximum frequency across all nodes and letters. ans = 0 for i in range(n): for j in range(26): ans = max(ans, dp[i][j]) print(ans)