Han pasado tres días y no hay soluciones, así que explico como se resuelve (aunque si se buscaba en Google el nombre del problema tal y como dije, explica en muchos sitios diferentes la solución).
La solución más eficiente es un algoritmo greedy que consiste en ordenar los intervalos por hora de final. Una vez hecho esto, se coge el primero y se va cogiendo el siguiente que no solape con el último cogido.
El último for de este algoritmo es lineal, por lo que la complejidad se ve dominada por el coste de ordenar, que usando un algoritmo eficiente como por ejemplo Merge Sort deja una complejidad de O(NlogN).
Otra solución menos eficiente pero válida con las restricciones que puse es la dinámica cuadrática que se puede hacer en función de la N, que tiene complejidad O(N2).
La idea de la dinámica es que M[ i] representa el máximo número de intervalos que puedo coger usando el i-ésimo en último lugar. Como están ordenados los intervalos por inicio (en el otro se ordenaba por final), el algoritmo planteado es correcto.
La solución más eficiente es un algoritmo greedy que consiste en ordenar los intervalos por hora de final. Una vez hecho esto, se coge el primero y se va cogiendo el siguiente que no solape con el último cogido.
Código (cpp) [Seleccionar]
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, int> PII;
bool comp(PII a, PII b) {
return (a.second < b.second) or (a.second == b.second and a.first < b.first);
}
int main() {
int n;
cin >> n;
vector<PII> v(n);
for (int i = 0; i < n; ++i) cin >> v[i].first >> v[i].second;
sort(v.begin(), v.end(), comp);
int cnt = 0, ant = -1;
for (int i = 0; i < n ; ++i) {
if (v[i].first >= ant) {
++cnt;
ant = v[i].second;
}
}
cout << cnt << endl;
}
El último for de este algoritmo es lineal, por lo que la complejidad se ve dominada por el coste de ordenar, que usando un algoritmo eficiente como por ejemplo Merge Sort deja una complejidad de O(NlogN).
Otra solución menos eficiente pero válida con las restricciones que puse es la dinámica cuadrática que se puede hacer en función de la N, que tiene complejidad O(N2).
Código (cpp) [Seleccionar]
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, int> PII;
int main() {
int n;
cin >> n;
vector<PII> v(n);
for (int i = 0; i < n; ++i) cin >> v[i].first >> v[i].second;
sort(v.begin(), v.end());
vector<int> M(n);
int res = 0;
for (int i = 0; i < n ; ++i) {
M[i] = 1;
for (int j = 0; j < i; ++j)
if (v[j].second <= v[i].first) M[i] = max(M[i], M[j] + 1);
res = max(res, M[i]);
}
cout << res << endl;
}
La idea de la dinámica es que M[ i] representa el máximo número de intervalos que puedo coger usando el i-ésimo en último lugar. Como están ordenados los intervalos por inicio (en el otro se ordenaba por final), el algoritmo planteado es correcto.