Treni (20/100) problemi con i subtask 4 e 5

Buon giorno a tutti, sto provando a risolvere il problema treni e ho scritto un codice che però risolve solo i subtask 1,2 e 3.
questo per prima cosa controlla se è ottimale optare per prendere il treno il primo giorno, e se sì, quale, poi controlla tutti i giorni fino al penultimo, facendo attenzione se sia conveniente o no prendere il treno affatto, all’ultimo giorno controlla la scelta che si era fatta il giorno prima (l’ha preso o non l’ha preso) e agisce di conseguenza, questo va bene fino al subtask 4, da lì in poi da sempre output sbagliato, se potete aiutarmi ne sarei molto felice, grazie.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int tempo_massimo(int N, int a[], int b[]){
    if (N == 1){
        if(a[0] > b[0]){
            return a[0];
        }else{
            return b[0];
        }
    }

    int tmax = 0, suma = 0, sumb = 0;
    bool prevsum = true;
    suma = a[1]+a[0];
    sumb = b[0]+a[1];
    if (suma > b[1] || sumb > b[1]){
        if(a[0] > b[0]){
            tmax = a[0];
        }else{
            tmax = b[0];
        }
        prevsum = false;
    }

    for(int i = 1; i < N-1; i++){
        if(prevsum){
            sumb = b[i]+a[i+1];
            if(sumb > b[i+1]){
                tmax += b[i];
                prevsum = false;
                continue;
            }else{
                prevsum = true;
                continue;
            }
        }
        suma = a[i+1]+a[i];
        if (suma>b[i+1]){
            tmax += a[i];
            prevsum = false;
        }else{
            prevsum = true;
        }
    }
    if(prevsum){
        tmax += b[N-1];
    }else{
        tmax += a[N-1];
    }

    return tmax;
}





int main()
{
    int n;
    FILE *in = stdin, *out = stdout;
    assert(fscanf(in, "%d", &n) == 1);

    int *a = (int*)calloc(n, sizeof(int));
    int *b = (int*)calloc(n, sizeof(int));

    for(int i=0; i<n; i++){
      assert(fscanf(in, "%d", a + i) == 1);
      assert(fscanf(in, "%d", b + i) == 1);
    }

    int answ = tempo_massimo(n, a, b);
    fprintf(out, "%d\n", answ);

    free(a);
    free(b);

    fclose(in);
    fclose(out);

    return EXIT_SUCCESS;
}

Il tuo codice fa i subtask 1, 2 e 3 per caso (o meglio, perché i testcase sono deboli). Infatti il caso:

1
1 1
1 8
1 10

è sufficiente a rompere il tuo programma.
Ci sono alcuni grossi hint del fatto che la tua logica sia rotta, come il fatto che controlli la somma dei treni che puoi prendere al giorno i e al giorno i+1 per fare la scelta del giorno i, ma poi ignori completamente quello che hai scelto il giorno prima quando fai la scelta del giorno i+1.
In ogni caso è impossibile trovare una soluzione ottimale greedy a questo problema (cioè considerando solo un numero finito di mosse future): per compiere una scelta ottimale devi considerare tutte le possibilità future (e infatti questo problema sta nella sezione dp di algobadge e non in quella greedy).

il formato del tuo input è sbagliato, dovrebbe essere:
3
1 1
1 8
1 10
perché nella prima riga c’è l’intero enne e poi da lì per altre N righe gli array “a” e “b”, col l’input giusto il programma funziona correttamente.
Comunque sapresti dirmi in maniera più concreta il motivo per cui la mia logica è “rotta”? Te ne sarei grato.

Sì ho scritto male l’input scusa. Comunque mi sembra che anche con l’input giusto il tuo programma stampi 10, laddove la risposta corretta è 11.

Comunque faccio un esempio in merito a perché la logica è rotta.
Prendiamo il caso:

3
1 1
1 8
1 10

Tu inizi analizzando le coppie di treni dei primi due giorni, e poiché b[1] > a[0]+a[1] e b[1]>b[0]+a[1] decidi che è ottimale non prendere nessun treno al primo giorno, facendo questo hai assunto già che il giorno dopo dovrai prendere il treno b[1].
Ecco però che quando analizzi il secondo e il terzo giorno ti accorgi che il treno b[1] non è poi così ottimale, visto che ti preclude la possibilità di prendere il treno b[2] che vale di più, e quindi decidi di non viaggiare neanche al secondo giorno. A questo punto però l’assunzione che avevi fatto nel momento di scegliere i treni del primo giorno cade, in quanto non avendo poi effettivamente preso il treno b[1], la rinuncia ai treni del primo giorno diventa totalmente inutile.

hai ragione, grazie per avermelo fatto notare.