Problema Medaglie, dubbio su algoritmo risolutivo

Buongiorno a tutti, ho un problema con l’esercizio Medaglie.
Questo è il nucleo ricorsivo per l’algoritmo che dovrebbe risolvere il problema.
Il problema delle prestazioni esponenziali e delle occupazioni dello stack eccessiva è già noto ed esite già una versione ottimizzata che condivide gli stessi problemi di base.
L’algoritmo risolve il primo set senza alcun problema, e 4 del secondo.

int best_choice(int L, long long int* V){
    if(L>=3)return V[0]-min3(best_choice(L-1,V+1),best_choice(L-2,V+2),best_choice(L-3,V+3));
    else if(L==2)return V[0]-min2(best_choice(L-1,V+1),best_choice(L-2,V+2));
    else if(L==1)return V[0]-best_choice(L-1,V+1);
    else return 0;
}

min3 è una funzione che restituisce il minore tra tre numeri e min2 fra due.
L è il numero di celle dell’array ancora da processare, mentre V contiene l’integrale dell’array di partenza.

La lettura del file e la popolazione degli array avviene come in seguito:

FILE *fr, *fw;
int N, i;

fr = fopen("input.txt", "r");
fw = fopen("output.txt", "w");
assert(1 == fscanf(fr, "%d", &N));

for(i=0; i<N; i++)
    assert(1 == fscanf(fr, "%d", &array[N-1-i]));

for(int i=0;i!=N+1;i++)support[i]=-1;
arrayI[N]=0;
for(int i=1;i!=N+1;i++){arrayI[N+1-i-1]=arrayI[N+1-i]+(array[i-1]*2+1)*100;}

for(int i=N-1;i>0;i-=1)best_choice_l(N-i,arrayI+1+i,support+i);

int test=best_choice_l(N,arrayI+1,support);
fprintf(fw, "%d\n", (int)(arrayI[0]-test));

Grazie per l’attenzione e buona giornata.

Ciao, non sono sicuro, potrebbe essere un problema legato ai long long? Dagli snippet postati mi pare che long long e int vengano mischiati in modo un po’ pericoloso

Ho controllato per premura ma non ci sono problemi con i tipi, il compilatore non dà nemmeno un warning e di solito è abbastanza schizzinoso al riguardo.
Tanto più il long long int è messo solo per evitare superamento dei limiti, cambiandolo con un semplice int nei casi più piccoli non cambia nulla e non funziona ugualmente.

Probabilmente non ho capito bene io la tua domanda, ma mi sembra di capire che la soluzione da te postata abbia una complessità esponenziale, come tra l’altro hai scritto anche tu.
Dovresti trovare un modo per rendere più veloce (e di diminuire le chiamate alla funzione nello stack) il tuo codice, ad esempio memorizzando valori che potrebbero essere riutilizzati in seguito…

A tal proposito ti potrebbe essere utile informarti sulla Programmazione Dinamica (DP) :slight_smile:

Ad esempio, tramite questa guida (pag. 64).

Ok grazie :slight_smile: ci darò un’occhiata.

Questo utente appartiene a mio fratello, ma il codice in origine l’ho scritto io :smile:
Quindi non ho una personalità multipla che mi porta a rispondere due volte alla stessa domanda :smiley:.
Mi scuso per la confusione.

Il codice inizialmente postato è evidentemente di complessità esponenziale, e non è in grado di terminare in tutti i casi nei tempi previsi. Esiste già una versione ottimizzata che appunto riutilizza i risultati dei sottoalberi già valutati. Se vuoi la posto, ma funziona (o meglio non funziona) esattamente negli stessi casi. Questo mi fa pensare una mia interpretazione erronea della traccia.
Per questo ho postato il codice più semplice, alla ricerca di un errore logico nella risoluzione.

Capito, però dal codice che hai postato non riesco a capire quale possa essere il problema, magari se ci lasci il codice completo della soluzione “corretta” è più facile capire se può esserci qualcosa di sbagliato

Per capire se c’è un errore nella logica dell’algoritmo usato prova a spiegarlo a parole, in modo che sia più facile per gli altri capire la strategia che hai usato :wink:

1 Mi Piace