Skip to Content

Movie Festival II

Solución en video

Por Hannah Ying

Nota: la solución en video puede no coincidir con las demás soluciones. Código en Java.

Video de YouTube (ZQMh4WHE3Wc)

Explicación

El primer paso es el mismo que el de Movie Festival; ordenar las películas en orden creciente de tiempo de fin. Para cada película en orden, la asignaremos a uno de los kk miembros para que la vea (o a ninguno).

Llevamos el tiempo en que cada miembro termina de ver todas las películas actualmente asignadas en un multiconjunto ordenado (representado por un TreeMap en Java o un multiset en C++). Inicialmente, la colección consiste en kk ceros.

Para cada película en orden, podemos asignar un miembro para verla si existe un elemento en la colección ordenada menor o igual al tiempo de inicio de la película. Si hay varios de esos elementos, elegimos el mayor (el miembro que terminó de ver sus películas asignadas más tarde). Asignamos al miembro a ver esta película incrementando la respuesta y actualizando la colección en consecuencia.

Implementación

Complejidad temporal: O(nlogk)\mathcal{O}(n\log k)

#include <algorithm> #include <iostream> #include <set> #include <vector> using namespace std; int main() { int n, k; cin >> n >> k; vector<pair<int, int>> v(n); for (int i = 0; i < n; i++) // read start time, end time cin >> v[i].second >> v[i].first; sort(begin(v), end(v)); // sort by end time int maxMovies = 0; multiset<int> end_times; // times when members will finish watching movies for (int i = 0; i < k; ++i) end_times.insert(0); for (int i = 0; i < n; i++) { auto it = end_times.upper_bound(v[i].second); if (it == begin(end_times)) continue; // assign movie to be watched by member in multiset who finishes at time // *prev(it) end_times.erase(--it); // member now finishes watching at time v[i].first end_times.insert(v[i].first); ++maxMovies; } cout << maxMovies; }
import java.io.*; import java.util.*; public class MovieFestival2 { public static void main(String[] args) { FastIO io = new FastIO(); int n = io.nextInt(); int k = io.nextInt(); Interval[] movies = new Interval[n]; for (int i = 0; i < n; i++) { movies[i] = new Interval(io.nextInt(), io.nextInt()); } // sort movies based on end time Arrays.sort(movies, Comparator.comparingInt(movie -> movie.end)); int maxMovies = 0; // times when members will finish watching their movies TreeMap<Integer, Integer> endTimes = new TreeMap<>(); endTimes.put(0, k); // initialize all members at time 0 for (Interval movie : movies) { // find member who finished watching their assigned movies the // latest before movie.start Integer lower = endTimes.floorKey(movie.start); // if such member exists, assign the member to the current movie if (lower != null) { maxMovies++; int lowerValue = endTimes.get(lower); // remove the original time in which member finishes movie if (lowerValue - 1 == 0) { endTimes.remove(lower); } else { endTimes.put(lower, lowerValue - 1); } // member now finishes watching at time movie.end endTimes.put(movie.end, endTimes.getOrDefault(movie.end, 0) + 1); } } io.println(maxMovies); io.close(); } static class Interval { int start, end; Interval(int start, int end) { this.start = start; this.end = end; } } // BeginCodeSnip{FastIO} static class FastIO extends PrintWriter { private InputStream stream; private byte[] buf = new byte[1 << 16]; private int curChar, numChars; // standard input public FastIO() { this(System.in, System.out); } public FastIO(InputStream i, OutputStream o) { super(o); stream = i; } // file input public FastIO(String i, String o) throws IOException { super(new FileWriter(o)); stream = new FileInputStream(i); } // throws InputMismatchException() if previously detected end of file private int nextByte() { if (numChars == -1) throw new InputMismatchException(); if (curChar >= numChars) { curChar = 0; try { numChars = stream.read(buf); } catch (IOException e) { throw new InputMismatchException(); } if (numChars == -1) return -1; // end of file } return buf[curChar++]; } // to read in entire lines, replace c <= ' ' // with a function that checks whether c is a line break public String next() { int c; do { c = nextByte(); } while (c <= ' '); StringBuilder res = new StringBuilder(); do { res.appendCodePoint(c); c = nextByte(); } while (c > ' '); return res.toString(); } public int nextInt() { // nextLong() would be implemented similarly int c; do { c = nextByte(); } while (c <= ' '); int sgn = 1; if (c == '-') { sgn = -1; c = nextByte(); } int res = 0; do { if (c < '0' || c > '9') throw new InputMismatchException(); res = 10 * res + c - '0'; c = nextByte(); } while (c > ' '); return res * sgn; } public double nextDouble() { return Double.parseDouble(next()); } } // EndCodeSnip{FastIO} }