#include #include #include #include using namespace std; #define NDEBUG const int MAX_N = 10000; // MAX_N/3 const int MAX_T = 3500; const int EMPTY = -1; int N; int sequenza[MAX_N]; int diff[MAX_N]; // Vettore per memoizzare. int mem[MAX_N][MAX_T]; // Scegli t coppie tra i primi n elementi (n incluso) in modo da minimizzare // le differenze tra gli elementi delle coppie. int risolviRicorsivo(int n, int t); int main() { ifstream in("input.txt"); assert(in); in >> N; assert( 1 <= N && N <= MAX_N ); for (int i = 0; i <= N-1; ++i) in >> sequenza[i]; in.close(); // Ordino gli elementi dal piu' piccolo al piu' grande. sort(sequenza, sequenza + N); // Calcolo le differenze in ordine. for (int i = 1; i <= N-1; ++i) diff[i] = sequenza[i] - sequenza[i-1]; for (int i = 0; i <= N; ++i) for (int j = 1; j <= floor(N/3); ++j ) mem[i][j] = EMPTY; int costo = risolviRicorsivo(N, floor(N/3)); ofstream out("output.txt"); out << costo << endl; out.close(); return 0; } int risolviRicorsivo(int n, int t) { assert(t <= floor(n/2)); // Caso base ho gia' scelto tutte le triplette. if (t == 0) return 0; // Istanza gia' risolta. if ( mem[n][t] != EMPTY ) return mem[n][t]; // Prendo la coppia corrente. int prendo = risolviRicorsivo(n-2, t-1)+diff[n-1]; // Scelta migliore tra salta questo elemento e prendi la coppia corrente. if (t <= floor((n-1)/2)) return mem[n][t] = min(risolviRicorsivo(n-1, t),prendo); return mem[n][t] = prendo; }