vivan esas clases de algoritmica!! estaba claro que era bactracking... lo unico una duda: para que usas el 0? simplemente no hace falta tenerlo en cuenta a la hora de hacer los calculos, ya que no conoce el 0 ni ninguno más allá del 5
EDITO: Voy a probar otro punto de vista. Mezcla de voraces y bactracking. Simplemente es ir cogiendo los numeros en orden (1,2,3,4,5) e ir añadiendo el numero actual a la suma, hasta que llegue al numero o me pase, momento en el que doy un paso atras en recursividad y cojo el siguiente:
por ejemplo para 3 sería
1
11
111 /* Es 3 luego paro y vuelvo atras */
112 /* Me he pasado, lo descarto y vuelvo atras */
12 /* Es 3 me vale, vuelvo atras */
121 /* Me he pasado, para atrás */
2
21 /* Me vale */
ad infinitum xD
EDITO LO EDITADO: He terminado mi algoritmo. Aquí pongo todo el código. He añadido lo de david para comparar llamadas recursivas y tiempo de ejecución.
En cuanto a diferencias, el tuyo está mejor porque no dependes de variables externas, a diferencia del mío.
- Código: Seleccionar todo
#include <vector>
#include <iostream>
#include <time.h>
typedef std::vector<int> Vi;
int valores[4] = {1,1,2,3};
int numeros_conocidos[4] = {1,4,2,3};
void numeros_gustavo(int& iteraciones,int& numeros, int numero_a_calcular, Vi& numeros_usados, int& suma)
{
int pos_actual = 0;
while(pos_actual < 4 && suma + valores[pos_actual] <= numero_a_calcular)
{
// Anotar
numeros_usados.push_back(numeros_conocidos[pos_actual]);
suma += valores[pos_actual];
numeros_gustavo(++iteraciones,numeros,numero_a_calcular, numeros_usados, suma);
//Desanotar
suma -= valores[pos_actual];
numeros_usados.pop_back();
pos_actual++;
}
if (suma == numero_a_calcular)
{
numeros++;
pos_actual = 4;
}
}
const int DigsGus[]= {0,1,1,2,3};
const int NDigGus = 5;
bool suma_n(const Vi& v, int n) {
int suma = 0;
for (int i = 0; i < v.size(); i++) {
suma += v[i];
}
return suma == n;
}
int numerosGus(int& iteraciones, Vi& v, int i, int n) {
if (i == n) {
return suma_n(v, n);
}
int nums = 0;
int j = 0;
if (v[std::max(i-1,0)] != 0) ++j;
while (j < NDigGus) {
v[i] = DigsGus[j];
nums += numerosGus(++iteraciones,v, i+1, n);
++j;
}
return nums;
}
int main(int argc, char* argv[])
{
int numero_a_calcular;
time_t tiempo, differ;
while( std::cin >> numero_a_calcular)
{
int numeros = 0, numeros2 = 0;
int suma_acumulada = 0;
int iteraciones = 0, iteraciones2 = 0;
Vi numeros_usados, numeros_usados2(numero_a_calcular, 0);
numeros_usados.reserve(numero_a_calcular + 10);
tiempo = time(NULL);
numeros_gustavo(iteraciones,numeros, numero_a_calcular, numeros_usados, suma_acumulada );
differ = time(NULL) - tiempo;
std::cout << "ITERACIONES Juan: " << iteraciones << " NUMEROS: " << numeros <<
" TIEMPO: " << differ << std::endl;
tiempo = time(NULL);
numeros2 = numerosGus(iteraciones2, numeros_usados2, 0, numero_a_calcular);
differ = time(NULL) - tiempo;
std::cout << "ITERACIONES David: "<< iteraciones2 << " NUMEROS: " << numeros2 <<
" TIEMPO: " << differ << std::endl;
}
}