Esercizi di Algoritmi e Strutture Dati



Похожие документы
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

10 - Programmare con gli Array

Corso di Laurea in Ingegneria Gestionale Esame di Informatica - a.a luglio 2013

Algoritmi di Ricerca. Esempi di programmi Java

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a giugno 2013

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

Esercizi di Algoritmi e Strutture Dati

Studente (Cognome Nome): Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Primo scritto 11 Gennaio 2008

Sono casi particolari di MCF : SPT (cammini minimi) non vi sono vincoli di capacità superiore (solo x ij > 0) (i, j) A : c ij, costo di percorrenza

Esercizi Capitolo 6 - Alberi binari di ricerca

Programmazione dinamica

Studente (Cognome Nome): Corso di Informatica Corso di Laurea in Ingegneria Gestionale a.a Secondo Compitino 21 Dicembre 2006

Algoritmi e Strutture Dati

LABORATORIO DI PROGRAMMAZIONE EDIZIONE 1, TURNO B

La gestione dell input/output da tastiera La gestione dell input/output da file La gestione delle eccezioni

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

4. Operazioni elementari per righe e colonne

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

3 - Variabili. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Uso di JUnit. Fondamenti di informatica Oggetti e Java. JUnit. Luca Cabibbo. ottobre 2012

SOMMARIO Coda (queue): QUEUE. QUEUE : specifica QUEUE

PROBLEMA DELLA RICERCA DI UN ELEMENTO IN UN ARRAY E ALGORITMI RISOLUTIVI

4 3 4 = 4 x x x 10 0 aaa

3. La sintassi di Java

Parcheggio.rtf 1/8 6 gennaio Prova di programmazione: parcheggio a pagamento

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a settembre 2011

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Introduzione al MATLAB c Parte 2

RICORSIVITA. Vediamo come si programma la soluzione ricorsiva al problema precedente: Poniamo S 1 =1 S 2 =1+2 S 3 =1+2+3

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

void funzioneprova() { int x=2; cout<<"dentro la funzione x="<<x<<endl; }

RICERCA OPERATIVA GRUPPO B prova scritta del 22 marzo 2007

Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati

Le variabili. Olga Scotti

ARRAY BIDIMENSIONALI float [][] mx = new float[3][4]; (float []) [] mx = new float[3][4];

Esempio: dest = parolagigante, lettere = PROVA dest (dopo l'invocazione di tipo pari ) = pprrlogvgante

Verifica della correttezza formale del numero di partita IVA

NOZIONI BASE SHELL E SCRIPT LINUX

Esercizi della lezione 5 di Java

Sottoprogrammi: astrazione procedurale

Programmazione ad Oggetti: JAVA. Esercitazione

Realizzazione di una classe con un associazione

INTRODUZIONE AGLI ALGORITMI INTRODUZIONE AGLI ALGORITMI INTRODUZIONE AGLI ALGORITMI INTRODUZIONE AGLI ALGORITMI

Gli array. Gli array. Gli array. Classi di memorizzazione per array. Inizializzazione esplicita degli array. Array e puntatori

Esercizi per il corso di Algoritmi e Strutture Dati

Programmazione ad Oggetti Modulo A (Esame del 11/9/2015)

Semantica Assiomatica

Alberi binari di ricerca

Fondamenti di Informatica T-1, 2009/2010 Modulo 2 Prova d Esame 5 di Giovedì 15 Luglio 2010 tempo a disposizione 2h30'

Esercitazione n 4. Obiettivi

Il tipo di dato astratto Pila

La selezione binaria

Prova di Laboratorio di Programmazione

Un esercizio d esame. Flavio De Paoli

Algoritmi e Strutture Dati & Laboratorio di Algoritmi e Programmazione

Concetto di Funzione e Procedura METODI in Java

Laboratorio di Informatica Lezione 2

Iniziamo con un esercizio sul massimo comun divisore: Esercizio 1. Sia d = G.C.D.(a, b), allora:

Ottava Esercitazione. introduzione ai thread java mutua esclusione

Esercitazione 6. Tutor: Ing. Diego Rughetti. Anno Accademico 2007/2008

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

4.1 Modelli di calcolo analisi asintotica e ricorrenze

Matematica - SMID : Programmazione Febbraio 2009 FOGLIO RISPOSTE

Parte 1. Vettori di bit - AA. 2012/13 1.1

Traccia di soluzione dell esercizio del 25/1/2005

Corso di Tecniche di Programmazione

Dimensione di uno Spazio vettoriale

ci sono più problemi che programmi esiste un problema che non si può risolvere con un programma

Esercizi Capitolo 5 - Alberi

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Algoritmi e Strutture Dati & Laboratorio di Algoritmi e Programmazione

Struttura di un programma Java

Tipi di Dato Ricorsivi

TSP con eliminazione di sottocicli

Descrizione di un algoritmo

SAPIENZA Università di Roma, Facoltà di Ingegneria

Introduzione a Visual Basic Lezione 1 Concetti base e istruzioni condizionali

Sequenziamento a minimo costo di commutazione in macchine o celle con costo lineare e posizione home (In generale il metodo di ottimizzazione

Prova d Esame Compito A

Fondamenti dell Informatica Ricorsione e Iterazione Simona Ronchi Della Rocca (dal testo: Kfoury, Moll and Arbib, cap.5.2)

GESTIONE INFORMATICA DEI DATI AZIENDALI

Testi di Esercizi e Quesiti 1

Esercizi sull Association Analysis

Introduzione alla tecnica di Programmazione Dinamica

Prestazioni CPU Corso di Calcolatori Elettronici A 2007/2008 Sito Web: Prof. G. Quarella prof@quarella.

Corso di Algoritmi e Strutture Dati Informatica per il Management Prova Scritta, 25/6/2015

Esercitazione N7:Gioco dei 21 fiammiferi (impariamo java giocando)

Esercizi su lineare indipendenza e generatori

Correttezza. Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1. Dispensa 10. A. Miola Novembre 2007

Esercizio 6 Realizzare una classe astratta per le Figure piane e due sottoclassi, la sottoclasse Quadrato e la sottoclasse Rettangolo.

EXCEL FUNZIONI PRINCIPALI

Corso di Laurea in Ingegneria Gestionale Esame di Informatica a.a I scritto Febbraio 11 Febbraio 2011

I file di dati. Unità didattica D1 1

1 Giochi a due, con informazione perfetta e somma zero

(Esercizi Tratti da Temi d esame degli ordinamenti precedenti)

Транскрипт:

Esercizi di Algoritmi e Strutture Dati Moreno Marzolla marzolla@cs.unibo.it 18 marzo 2011 Problema basato su 10.5 del libro di testo La CINA (Compagnia Italiana per il Noleggio di Automobili) dispone di k automobili, tutte disponibili per n giorni. Una stessa automobile può avere costo di affitto diverso in giorni diversi: indicheremo con c(a, g) il costo per il noleggio dell automobile a nel giorno g, dove 1 a k e 1 g n. Un cliente si rivolge alla CINA per procurarsi un mezzo di locomozione per l intero periodo (giorni da 1 a n, estremi inclusi). Per risparmiare e sfruttare i prezzi di noleggio migliori in ogni giornata il cliente è disposto a cambiare macchina da un giorno all altro. Per ottenere un cambio, però, è costretto dalla CINA a pagare una penale P, che si aggiunge al costo di noleggio. Il costo di una sequenza di noleggio è quindi dato dalla somma dei costi di noleggio e delle penali pagate per i cambi. Dati k, n, i costi c(a, g) e la penale P : 1. Calcolare il numero di possibili sequenze di noleggio diverse. 2. Scrivere un algoritmo che elenchi tutte le possibili sequenze di noleggio. Una sequenza di noleggio è un vettore di n numeri (v 1, v 2,... v n ) tale che per ogni i 1,... n, 1 v i k rappresenta il numero dell auto noleggiata nel giorno i. 3. Scrivere un algoritmo che calcoli la sequenza di noleggio di costo minimo, nell ipotesi in cui la penale P sia pari a zero. 4. Proporre un algoritmo che in tempo O(nk 2 ) calcoli la spesa minima per il cliente tra tutte le possibili sequenze di noleggio, assumendo una penale P > 0 (Suggerimento: usare la programmazione dinamica); 5. Modificare l algoritmo proposto al punto precedente in modo da avere in output la sequenza di noleggio di costo minimo. La modifica deve avere costo additivo O(nk). Soluzione 1. Il numero delle possibili sequenze di noleggio è k n. Quindi un eventuale algoritmo risolutivo che operi di forza bruta non sarebbe praticabile. 2. (Vedi programma Java) 3. In questo caso è possibile sviluppare una soluzione semplice: per ogni giorno, è sufficiente scegliere l auto che ha costo di noleggio minimo in quello specifico giorno. 4. Supponiamo che Cost(i, j) sia il costo minimo tra tutte le sequenze di noleggio durante i primi j giorni, che al giorno j-esimo usino l auto i, con 1 j n, e 1 i k. Considerando i noleggi solo per il primo giorno (j = 1), possiamo scrivere: Cost(i, 1) = c(i, 1), per ogni i = 1, 2,... k Nel caso di sequenze di noleggio che durano fino al giorno j, per j > 1, l acquirente ha a disposizione le seguenti alternative: 1

Può noleggiare la stessa audo i noleggiata nel giorno j 1. Il costo ottimo fino al giorno j 1 è Cost(i, j 1), a cui si somma il costo di noleggio della vettura i per il giorno j senza pagare alcuna penale. In tal caso si avrebbe: Cost(i, j) = Cost(i, j 1) + c(i, j) Può noleggiare un auto l i nel giorno j 1, e cambiare scegliendo l auto i nel giorno j. In tal caso il costo di noleggio Cost(i, j) diventa Cost(i, j) = Cost(l, j 1) + c(i, j) + P Il costo della sequenza ottima di noleggio Cost(i, j) che al giorno j usa l auto i sarà quindi il minimo tra le alternative descritte sopra, ossia: Cost(i, j) = mincost(i, j 1)+c(i, j), Cost(l, j 1)+c(i, j)+p per ogni l = 1, 2,... k, l i Il risultato del nostro problema, ossia il costo minimo tra tutte le sequenze di noleggio per tutti gli n giorni, è dato dal valore minimo dell ultima colonna della matrice Cost, ossia min Cost(i, n) 1 i k 5. Per determinare la sequenza che minimizza il costo di noleggio, una soluzione efficiente consiste nell utilizzare una matrice ausiliaria di dimensione k n che chiameremo prev(i, j), tale che prev(i, j) è l auto utilizzata il giorno j 1 per ottenere il costo Cost(i, j) al giorno j. La sequenza ottima di noleggio si ottiene ripercorrendo all indietro la matrice prev a partire dalla posizione nell ultima colonna che rappresenta l ultima vettura noleggiata; ricordiamo che l indice dell ultima vettura noleggiata è il valore di i che minimizza Cost(i, n). La soluzione con costo additivo O(nk) invece fa uso della sola tabella Cost(i, j) per calcolare la sequenza di noleggio, ripercorrendo la tabella a ritroso per ricostruire le scelte fatte. Consideriamo un semplice esempio con penale P = 0.5, k = 3, n = 4 e matrice dei costi giornalieri c(a, g) come segue: 1 1 1 2 c(a, g) = 0.5 1 7 4 0.9 1.2 0.1 10 Applicando l algoritmo descritto sopra, si ottiene la seguente matrice dei costi Cost(i, j): 1.0 2.0 3.0 4.6 Cost(i, j) = 0.5 1.5 8.5 6.6 0.9 2.1 2.1 12.1 e la seguente matrice prev: prev(i, j) = 1 0 0 2 1 1 1 2 1 2 1 2 Il seguente programma Java risolve l esercizio proposto: / CINA.java calcola la sequenza ottima di noleggio. Questo programma risolve il problema 10.5 p. 275 di Demetrescu, Finocchi, Italiano, Algoritmi e strutture dati (seconda edizione ), McGraw Hill, 2008. Version 0.1 del 2010/02/24 Autore: Moreno Marzolla (marzolla (at) cs.unibo. it ) 2

This file has been released by the author in the Public Domain public class CINA int k; // numero di auto int n; // lunghezza del periodo, in giorni double c [][]; // C[i ][ m] e il costo di noleggio dell auto i nel giorno m double P; // penale da pagare per i cambi // tabella di programmazione dinamica: cost[ i,m] e il costo // minimo di tutte le sequenze di noleggio, fino al giorno m // compreso, che hanno l auto i come auto prenotata per il giorno // m double cost [][]; int prev [][]; // Assumendo di scegliere l auto i al giorno j, // prev[ i ][ j ] indica il numero di auto noleggiata il // giorno j 1 che consente di ottenere il costo // cost [ i ][ j ] dell intera sequenza di noleggio public CINA( int k, int n, double c [][], double P ) this.k = k; this.n = n; this.c = c; this.p = P; cost = new double[k][n]; prev = new int[k][n ]; Stampa il contenuto delle tabelle di programmazione dinamica. public void stampatabella( ) int i, j ; System.out. println ( cost[ i ][ j ] ); for ( i=0; i<k; ++i ) for ( j=0; j<n; ++j ) System.out. print (cost [ i ][ j]+ ); System.out. println (); System.out. println ( prev[ i ][ j ] ); for ( i=0; i<k; ++i ) for ( j=0; j<n; ++j ) System.out. print (prev[ i ][ j]+ ); System.out. println (); Stampa le informazioni di una singola sequenza di noleggio protected void stampasequenza( int s [] ) double tot=0.0; for ( int i=0; i<n; ++i ) System.out. print ( g= +i+ /a= +s[i]+ /c= +c[s[i]][i]+ ); tot += c[s[i ]][ i ]; if ( i>0 ) if (s[ i ]!= s[ i 1]) tot+=p; System.out. println ( Totale= +tot); 3

Data una sequenza di noleggio s [], modifica s [] per restituire la successiva sequenza di noleggio. Ritorno false se s [] era l ultima sequenza della serie, true altrimenti. public boolean incrementasequenza(int s [] ) int i=0; while( i<n && s[i] == k 1 ) s[ i ] = 0; ++i; if ( i<n ) s[ i ] += 1; return true; else return false ; Stampa tutte le possibili sequenze di noleggio public void stampatuttesequenze( ) int [] s = new int[n]; // s[ i ] indica l auto da noleggiare il giorno i int i ; int c=0; // numero di sequenze di noleggio // Inizializziamo la sequenza iniziale (0, 0,... 0) for ( i=0; i<n; ++i ) s[ i ] = 0; do ++c; stampasequenza(s); while(incrementasequenza(s)); System.out. println ( Ci sono +c+ sequenze di noleggio ); Stampa la sequenza ottima di noleggio, Prima di invocare questa funzione, e necessario aver invocato l operazione CalcolaSequenzaOttima(). public void stampasequenzaottima( ) int [] s = new int[n]; int imin = 0; double cmin = cost [0][ n 1]; for ( int tmp=1; tmp<k; ++tmp) if ( cost [tmp][n 1] < cmin ) cmin = cost[tmp][n 1]; s[n 1] = imin; for ( int j=n 2; j>=0; j) imin=prev[imin][ j+1]; s[ j]=imin; stampasequenza(s); Questa funzione calcola la sequenza ottima di noleggio, e restituisce il costo ottimo. public double CalcolaSequenzaOttima( ) 4

int i, j ; // inizializziamo la tabella. I costi al giorno 1 sono noti, e // sono pari al costo di noleggio delle vetture // // Quindi: cost [ i ][0] = c[i ][0] per ogni i=0..k 1 for ( i=0; i<k; ++i) cost [ i ][0] = c[i ][0]; prev[ i ][0] = 1; // non ci sono auto precedenti al giorno 0 // calcoliamo ora i valori degli altri elementi della tabella // di programmazione dinamica, procedendo una colonna alla // volta, da sinistra verso destra. // // Il costo minimo di tutte le sequenze di noleggio fino al giorno // j, che noleggiano l auto i al giorno j e dato dal minimo // tra i costi seguenti : // Il costo delle sequenze di noleggio che hanno l auto i anche // al giorno precedente j 1 (cost[ i ][ j 1]), sommato al costo // dell auto i al giorno j (c[ i ][ j ]). In questo caso non c e // altro da aggiungere, perche non si pagano penali // Il costo minimo considerando le sequenze di noleggio che // al giorno ( j 1) noleggiano un auto diversa da i, pagando // quindi una penale. Tale costo minimo sara // min per ogni l!= i cost [ l ][ j 1] + c[i ][ j ] + P // // L equazione e // cost [ i ][ j ] = min cost[ i ][ j 1] + c[i ][ j ], // cost [ l ][ j 1] + c[i ][ j ] + P per ogni l!=i for ( j=1; j<n; ++j) for ( i=0; i<k; ++i) int imin = i; // auto al giorno j 1 che minimizza il // costo al giorno j double cmin = cost[i ][ j 1]+c[i][ j ]; // costo minimo al giorno j for ( int tmp=0; tmp<k; ++tmp) if ( tmp!= i ) // il caso tmp == i e gia // stato considerato con // l inizializzazione di imin e // cmin if ( cost [tmp][j 1] + P + c[i][ j ] < cmin ) cmin = cost[tmp][j 1] + P + c[i][ j ]; imin = tmp; // riempiamo la entry della tabella di programmazione // dinamica. cost [ i ][ j ] = cmin; prev[ i ][ j ] = imin; // Il risultato finale e il minimo valore dell ultima colonn // della tabella di programmazione dinamica double cmin = cost [0][ n 1]; for ( int tmp=1; tmp<k; ++tmp) if ( cost [tmp][n 1] < cmin ) cmin = cost[tmp][n 1]; return cmin; public static void main( String [] args ) 5

double [][] c = 1, 1, 1, 2, 0.5, 1, 7, 4, 0.9, 1.2, 0.1, 10 ; CINA solver = new CINA(3, 4, c, 0.5); System.out. println ( Elenco di tutte le sequenze di noleggio ); solver.stampatuttesequenze(); System.out. println ( \ncosto sequenza di noleggio ottima ); System.out. println ( solver.calcolasequenzaottima()); System.out. println ( \ntabelle di programmazione dinamica ); solver.stampatabella(); System.out. println ( \nsequenza di noleggio ottima ); solver.stampasequenzaottima(); Problema basato sul problema 10.7 del libro di testo Si supponga di avere n files F 1, F 2,... F n in cui il file i occupa w(f i ) MB. Supponiamo che tutti i w(f i ) siano interi (ossia, ciascun file occupa un multiplo intero di un MB). Vogliamo individuare, se esiste, un sottoinsieme S di F 1, F 2,... F n tale che la dimensione dei files presenti in questo sottoinsieme sia esattamente pari a 650MB: w(f ) = 650 F S In caso tale sottoinsieme S esista, vogliamo anche sapere quali sono i files che vi appartengono. Soluzione Consideriamo una matrice B(i, j) tale che ogni elemento della matrice sia un valore booleano (vero o falso). In particolare, B(i, j) è vero se e solo se esiste un sottoinsieme di files S di F 1, F 2,... F i la cui dimensione totale sia esattamente pari a j; ossia: w(f ) = j F S Per definizione si ha che B(1, w(f 1 )) = true e B(i, 0) = true per ogni i = 1, 2,... n (il sottoinsieme vuoto ha dimensione zero). Inoltre risulta B(i, j) = B(i 1, j) B (i 1, j w(f i )) La spiegazione è la seguente: esiste un sottoinsieme S di F 1, F 2,... F i la cui dimensione è j se vale una tra le seguenti proprietà esiste un sottoinsieme S di F 1, F 2,... F i 1 tale che F S w(f ) = j. In tal caso S = S è la soluzione e il file F i non ne fa parte. esiste un sottoinsieme S di F 1, F 2,... F i 1 tale che F S w(f ) = j w(f i). In tal caso la soluzione al nostro problema è S = S F i, e il file F i fa parte di S. Questo suggerisce di calcolare la matrice B utilizzando la programmazione dinamica. Si presti attenzione che l indice j w(f j ) potrebbe diventare negativo. In tal caso si assume che il corrispondente valore B (i 1, j w(f i )) sia falso. Una volta calcolata la matrice B(i, j) per ogni i = 1, 2,... n e j = 0,... 650, possiamo concludere the esiste un sottoinsieme di files la cui dimensione totale è 650MB se e solo se B(n, 650) ha valore true. Per determinare anche quali sono i files che fanno parte della soluzione (se esiste), è necessario usare un altra matrice booleana P (i, j), tale che P (i, j) vale true se e solo se il file i-isimo appartiene ad un sottoinsieme S di F 1, F 2,... F i la cui dimensione totale è pari a j (cioè F S w(f ) = j). Durante la costruzione di B(i, j) è possibile costruire la matrice P (i, j). L elenco dei files che appartengono alla soluzione può essere visualizzata con il seguente pseudocodice: 6

d:=650; i:=n; while (d>0) do if ( P(i,d) ) then stampa i; d := d - w(f_i); endif i := i-1; endwhile / Copiatutto. java determina se un insieme di files la cui dimensione complessiva e 1300MB puo essere suddivisa in due CDRom da 650MB ciascuno, e in caso affermativo stampa la suddivisione. Questo programma risolve il problema 10.7 p. 275 di Demetrescu, Finocchi, Italiano, Algoritmi e strutture dati (seconda edizione ), McGraw Hill, 2008. Version 0.1 del 2010/02/24 Autore: Moreno Marzolla (marzolla (at) cs.unibo. it ) This file has been released by the author in the Public Domain public class Copiatutto int [] w; // w[i ] e la dimensione ( in MB) del file i esimo int n; // numero di files boolean [][] B; // B[i ][ j ] = true sse e possibile riempire j MB di // spazio usando un sottoinsieme dei files 0, //... i boolean [][] P; // P[i ][ j ] = true sse il file i e nell insieme di // files la cui dimensione complessiva e j public Copiatutto( int w[] ) this.w = w; this.n = w.length; B = new boolean[n][651]; P = new boolean[n][651]; Stampa la lista dei files la cui dimensione complessiva e pari a 650MB. public void stampasoluzione( ) if (!B[n 1][650] ) return ; // non esiste soluzione int d=650; int i=n 1; System.out. println ( I seguenti files sono sul primo CD ROM ); while( d>0 ) if ( P[i ][ d] ) System.out. print ( i+ (s= +w[i]+ ) ); d =w[i]; i=i 1; System.out. println (); Risolve il seguente problema: dati n files le cui dimensioni 7

sono w[0], w[1],... w[n 1], esiste un sottoinsieme di tali files la cui dimensione sia esattamente pari a 650? Notare che se la dimensione complessiva di tutti i files e 1300MB, allora se questa funzione restituisce true e possibile copiare i files su due CDRom da 650MB senza spezzare nessun file. public boolean solve( ) int i, j ; // Inizializza B a false for ( i=0; i<n; ++i ) for ( j=0; j<651; ++j ) B[i ][ j ] = false ; P[i ][ j ] = false ; B[i ][0] = true; // Inizializza B[0][ w[0]] a true B[0][w[0]] = true; P [0][ w[0]] = true; for ( i=1; i<n; ++i ) for ( j=0; j<651; ++j) if ( B[i 1][j ] ) B[i ][ j ] = true; else if ( j >= w[i] && B[i 1][j w[i]] ) B[i ][ j ] = true; P[i ][ j ] = true; // aggiungi il file i esimo // alla soluzione // Restituisce la risposta return B[n 1][650]; public static void main( String [] args ) // Attenzione, la somma delle dimensioni NON e 1300MB; // l implementazione restituisce comunque true, poiche // risolve il problema che consiste nel trovare un sottinsieme // di files la cui dimensione complessiva e 650MB. int w[] = 330, 100, 310, 10, 80, 10 ; Copiatutto problema = new Copiatutto(w); if ( problema.solve ()) problema.stampasoluzione(); else System.out. println ( Il problema non ammette soluzione ); 8