//#define NDEBUG // NDEBUG definita nella versione che consegno #include #ifndef NDEBUG # include // uso di cin e cout non consentito in versione finale #endif #include #include #include #include #define MAX_N 1000 #define MAX_K 1000 using namespace std; int N = 0; int K = 0; int mat[MAX_N][3]; int disp[MAX_N][3]; // Metodo per il massimo int mymax( int a, int b ) { return (a>b) ? a : b; } // Metodo che ritorna se รจ possibile avanzare su quella casella bool PossibileDirezione(int r, int c) { ////cout << "PossDir: r2 = " << r2 << " c2 = " << c2 << "\n"; if((r >= 0 && r < N) && (c >= 0 && c < 3) && disp[r][c] == 1) return true; else return false; } int CercaRicoprimento(int r, int c, int k) { //// Stampa /* cout << "CercRic: r = " << r << " c = " << c << " k = " << k << "\n"; for(int i = 0 ; i < N ; i++) { for(int j = 0 ; j < 3 ; j++) { cout << disp[i][j] << " "; } cout << "\n"; } cout << "\n"; */ int max = 0; if(k>0) { // Ciclo per cercare in tutte le possibili direzioni per quella tessera for(int i = r ; i < N ; i++) { for(int j = 0 ; j < 3 ; j++) { ////cout << "i = " << i << " j = " << j << "\n"; int maxDestra = 0; int maxBasso = 0; if(disp[i][j] == 1) { // Se verso DESTRA if(PossibileDirezione(i,j+1)) { ////cout << "DESTRA SI\n"; // Modifica della matrice delle caselle disponibili disp[i][j] = 0; disp[i][j+1] = 0; // Condizione per proseguire nel giusto ordine una volta disposta la tessera if(j+2 <= 2) maxDestra = (mat[i][j]+mat[i][j+1]) + CercaRicoprimento(i,j+2,k-1); // chiamata ricorsiva verso destra sulla stessa riga else maxDestra = (mat[i][j]+mat[i][j+1]) + CercaRicoprimento(i+1,0,k-1); // chiamata ricorsiva verso il basso sulla riga successiva // Ripristino della matrice delle caselle disponibili disp[i][j] = 1; disp[i][j+1] = 1; } // Se verso il BASSO if(PossibileDirezione(i+1,j)) { ////cout << "BASSO SI\n"; // Modifica della matrice delle caselle disponibili disp[i][j] = 0; disp[i+1][j] = 0; // Condizione per proseguire nel giusto ordine una volta disposta la tessera if(j+1 <= 2) maxBasso = (mat[i][j]+mat[i+1][j]) + CercaRicoprimento(i,j+1,k-1); // chiamata ricorsiva verso destra sulla stessa riga else maxBasso = (mat[i][j]+mat[i+1][j]) + CercaRicoprimento(i+2,0,k-1); // chiamata ricorsiva verso il basso sulla riga successiva // Ripristino della matrice delle caselle disponibili disp[i][j] = 1; disp[i+1][j] = 1; } } max = mymax(max, maxDestra); max = mymax(max, maxBasso); } } } ////cout << "max = " << max << "\n"; return max; } int main() { ifstream fin("input.txt"); assert( fin ); ofstream fout("output.txt"); assert( fout ); fin >> N; fin >> K; ////cout << N << " " << K << "\n"; mat[N][3]; disp[N][3]; // Ciclo di lettura e inizializzazione della matrice di input e della matrice di supporto for(int i = 0 ; i < N ; i++) { for(int j = 0 ; j < 3 ; j++) { fin >> mat[i][j]; disp[i][j] = 1; // 1 = casella non coperta da una tessera, 0 = casella coperta da una tessera } } //// Stampa /* for(int i = 0 ; i < N ; i++) { for(int j = 0 ; j < 3 ; j++) { cout << mat[i][j] << " "; } cout << "\n"; } cout << "\n"; */ // Chiamata alla procedura ricorsiva int max = CercaRicoprimento(0,0,K); ////cout << "Max = " << max << "\n"; fout << max << "\n"; fin.close(); fout.close(); return 0; }