Bueno, ya he escrito mi propuesta, ha costado un poco más de lo que esperaba y al final lo he hecho en C++. La idea básica es buscar la cadena más larga que sea decreciente, y quitarla. Aplicamos esto recursivamente hasta que se acaben los caracteres.
Bueno, ahí va el código:
#include <iostream>
#include <string>
#include <list>
#include <algorithm>
using namespace std;
int streak(list<char> &sl)
{
list<char>::iterator i=sl.begin(), start=i;
while(i!=sl.end())
{
if(*i<=*start)
{
start=i;
i=sl.erase(i);
}
else i++;
}
return sl.size();
}
int main()
{
string s;
cin >> s;
int line = 1;
while (s != "end")
{
int n=1;
list<char> sl(s.size());
copy(s.begin(),s.end(),sl.begin());
while(streak(sl)>0)
n++;
cout << "Case " << line++ << ": " << n << endl;
cin >> s;
}
}
Y el test de que funciona:
franjesus@altamira:~/tmp$ ./test
ABC
Case 1: 3
CBA
Case 2: 1
CBACBA
Case 3: 2
CCCCCCCCCBBBBBBBBBAAAAAAAAAAA
Case 4: 1
CCCNBBBNAAA
Case 5: 2
CBACBACBA
Case 6: 3
ACMICPC
Case 7: 4
ANABMCAANABMCA
Case 8: 4
end
Me estoy cansando (he estado casi 3 horas con el problemita de marras). El problema C puede que tarde :-)
2 comentarios:
No hace falta calcular la LIS (longest increasing sequence). Se puede hacer con otro greedy más sencillo. De todas maneras está muy bien la solución. Pruebala en la ACM de todos modos!
¿Qué es un greedy? :-D
Me suena, pero no soy informático, hago estas cosas calentándome el coco. Tal vez debería estudiar algo de esto. Seguro que me ayudaría con la tesis...
Publicar un comentario