IOI'94 - Giorno 2 - Problema 2: Gli autobus

Un uomo arriva ad una fermata d'autobus alle 12:00, e vi rimane per il periodo 12:00-12:39. La fermata viene usata da un certo numero di linee di autobus. L'uomo prende nota degli istanti di arrivo degli autobus, che sono dati come input del problema. Si trovi il minimo numero di linee di autobus che soddisfino l'input. Per ogni linea, si dia l'istante di prima fermata e la frequenza (cioè, il tempo che intercorre fra un arrivo e il successivo).

Dati di input

Il file di input, INPUT.TXT, contiene un numero n (n<=300) che indica quanti arrivi di autobus sono stati registrati, seguito dai tempi di arrivo in ordine crescente. Nel nostro esempio:
17
0 3 5 13 13 15 21 26 27 29 37 39 39 45 51 52 53

Dati di output

I risultati vanno scritti sul file OUTPUT.TXT con una riga per ciascuna linea di autobus. Ogni linea contiene l'istante del primo arrivo e la frequenza, in minuti. L'ordine in cui compaiono le linee non è importante; se ci sono più soluzioni, se ne deve comunque produrre una sola. Nel nostro esempio:
0 13
3 12
5 8




Terminologia

Useremo la seguente terminologia per discutere del problema: Notate che s<p (la frequenza non può essere minore o uguale dell'istante del primo passaggio), e inoltre s+p<60 (ogni autobus passa almeno due volte). Da questo segue che 2s<60, cioè 0<=s<=29. Inoltre s+1<=p<=59-s (cioè 59-2s possibili valori di p). Ne segue che gli schedules possibili sono solo 59+57+55+...+1, che
significa SOMMA(i=0,...,29) (2i+1), cioè 30+2*SOMMA(i=0,...,29) i=30+2*29*30/2=30+870=900.
 

Algoritmo


L'algoritmo inizia con una fase in cui vengono precomputati (e posti in un array) i soli schedule  ammissibili rispetto alla sequenza di passaggi di input.
A questo punto inizia la ricerca basata su un branch-and-bound. Si parte dalla soluzione parziale vuota e si tenta di estenderla aggiungendo ogni volta schedule ammissibili rispetto ai passaggi rimanenti dopo la soluzione parziale corrente: i passaggi rimanenti sono conservati nell'array rec che viene ogni volta aggiornato quando si aggiunge/toglie uno schedule alla soluzione. Per evitare di considerare due volte la stessa soluzione parziale, la sequenza degli schedule della soluzione parziale è non decrescente (rispetto all'ordine degli indici degli schedule nell'array degli schedule ammissibili).

Si possono verificare i seguenti casi:

Notate inoltre che è inutile procedere se la lunghezza della soluzione parziale+1 non è minore dell'ottimo corrente.
Per ridurre ulteriormente i casi da considerare, supponete che l'array degli schedule ammissibili sia ordinato in ordine decrescente di numero di passaggi. Supponiamo ora di avere una certa soluzione parziale s1,...,sk e che il numero di passaggi di sk sia p. Supponiamo inoltre che i passaggi rimanenti siano r e che l'ottimo corrente sia costituito da n schedules. Perché la soluzione parziale possa diventare ottima occorre che la si possa estendere con meno di n-k schedules, ciascuno dei quali avrà non più di p passaggi: quindi dovrà essere t*p>=r per qualche r<n-k. E dunque (n-k)*p>r. Se non è così, è inutile provare ad estendere la soluzione...