Moovie Mooving
Solución en video
Nota: La solución en video podría no ser la misma que las otras soluciones. Código en C++.
Video de YouTube (oKm_GZD9u1E)
Implementación
Complejidad temporal:
#include <bits/stdc++.h>
using namespace std;
int N, L;
vector<vector<int>> schedule;
vector<vector<vector<int>>> next_show;
vector<int> length;
vector<pair<int, int>> dp;
// BeginCodeSnip{bit operations}
int pct(int x) { return __builtin_popcount(x); }
int setbit(int n, int k) { return (n | (1 << k)); }
int getbit(int n, int k) { return (n & (1 << k)) >> k; }
// EndCodeSnip
int find_show_time(int t, int m) {
auto it = upper_bound(schedule[m].begin(), schedule[m].end(), t);
if (it == schedule[m].begin()) { return -1; }
int start = *(it - 1);
if (start + length[m] < t || start > t) { return -1; }
return (it - 1) - schedule[m].begin();
}
int main() {
ifstream cin("movie.in");
ofstream cout("movie.out");
cin >> N >> L;
length.resize(N);
schedule.resize(N);
next_show.resize(N, vector<vector<int>>(N, vector<int>(0, -1)));
for (int i = 0; i < N; i++) {
int t, v;
cin >> t >> v;
length[i] = t;
int a;
while (v) {
cin >> a;
schedule[i].push_back(a);
v--;
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == j) continue;
for (int ii = 0; ii < schedule[i].size(); ii++) {
next_show[i][j].push_back(
find_show_time(schedule[i][ii] + length[i], j));
}
}
}
// dp[x] = {última_película, índice_en_el_horario_de_la_última_película}
dp.resize(1 << N, {-1, -1});
int ans = N + 1;
dp[0] = {0, 0};
// bucle sobre subconjuntos del horario
for (int i = 0; i < 1 << N; i++) {
if (dp[i].first == -1) continue;
for (int j = 0; j < N; j++) {
// ¿ya se vio la película j?
if (getbit(i, j)) continue;
int subset = setbit(i, j);
int x;
if (i == 0) {
x = schedule[j][0] == 0 ? 0 : -1;
} else {
x = next_show[dp[i].first][j][dp[i].second];
}
if (x != -1) {
// subconjunto que incluye a j
if (dp[subset].first == -1 ||
schedule[dp[subset].first][dp[subset].second] +
length[dp[subset].first] <
schedule[j][x] + length[j]) {
dp[subset] = {j, x};
}
if (schedule[dp[subset].first][dp[subset].second] +
length[dp[subset].first] >=
L) {
ans = min(ans, pct(subset));
}
}
}
}
cout << (ans == N + 1 ? -1 : ans) << endl;
}