/* FILE: FrameStewartConjecture.cpp last change: 16-Sep-2013 author: Romeo Rizzi * a solver for problem FrameStewartConjecture based on dynamic programming */ //#define NDEBUG // NDEBUG definita nella versione che consegno #include #ifndef NDEBUG # include // uso di cin e cout non consentito in versione finale #endif #include using namespace std; const int MAX_N = 10000; int n; const int MAX_K = 30; int k; const int OVERFLOW = -1; long int FS[MAX_N+1][MAX_K+1]; // FS[i][j] = the minimum number of moves in order to transport the tower according to a strategy obeying the Frame-Stewart conditions. long int min (long int a, long int b) { return (a> n >> k; fin.close(); // casi base: for(int j = 3; j <= k; j++) { FS[0][j] = 0; // nessun disco e' caso base for(int i = 1; i < j; i++) // meno dischi di pioli e' caso base FS[i][j] = 1 +2*(i-1); } for(int i = 1; i <= n; i++) if( FS[i-1][3] == OVERFLOW ) FS[i][3] = OVERFLOW; else { FS[i][3] = 1+2*FS[i-1][3]; // 3 pioli (classic Hanoi) e' caso base if ( FS[i][3] < FS[i-1][3] ) FS[i][3] = OVERFLOW; // overflow check } // step: for(int j = 4; j <= k; j++) for(int i = j; i <= n; i++) { FS[i][j] = OVERFLOW; for(int tip = 1; tip < i; tip++) { if( FS[tip][j] == OVERFLOW ) continue; if( FS[i-tip][j-1] == OVERFLOW ) continue; long int tmp = 2*FS[tip][j] + FS[i-tip][j-1]; if( tmp < FS[i-1][j] ) continue; // se overflow nella computazione di tmp if( FS[i][j] == OVERFLOW ) FS[i][j] = tmp; if( tmp < FS[i][j] ) FS[i][j] = tmp; } } ofstream fout("output.txt"); fout << FS[n][k] << endl; fout.close(); //few lines of code to experimentally determine the border: // for(int j = 3; j <= k; j++) { // int i = 0; // while( (FS[i+1][j] != OVERFLOW) && (i < n) ) i++; // cout << "with " << j << " poles we get till n = " << i << endl; // } return 0; }