/** Implementation of Nohl's algorithm for Pharaoh's Golden Staircase ** ** problem: ** ** Daniel E. Nohl, "Solving the Pharaoh's Golden Staircase Problem through ** ** Dynamic Programming", CCSC: Midwestern Conference, pp 54--60, 2004. ** ** ** ** Implemented by Abhijit Das on 15-Oct-2014. **/ #include #include #include #define NDFT 20 #define MDFT 10 #define MAXWD 5 #define MAXHT 5 #define INFINITY 1234567890 /* Generate n steps of random widths and heights */ void initSteps ( int n, int *W, int *H ) { int i; for (i=0; i j) printf(" "); else printf("%5d", M[i][j]); } printf("\n"); } } /* This function computes the optimal cost of replacing n controllers by m controllers, where m <= n. The merge-cost array M[][] is also passed as an input argument. The two-dimensional array T[][] stores the optimum costs. More precisely, T[i][j] stores the optimum cost of replacing the FIRST i+1 controllers C_0 to C_i by j+1 controllers C_0 to C_j, where j <= i. The other output array S[][] stores the solution, that is, S[i][j] stores the index where the last controller C_j should be placed so that the restructuring cost is T[i][j]. The desired output is stored at T[n-1][m-1]. */ void calcOptimalSoln ( int n, int m, int **M, int **T, int **S ) { int i, j, thiscost, k; /* Replacing C_0 to C_i by C_0 to C_i calls for no cost */ for (i=0; i= j. The case i = j is already handled */ for (i=j+1; i= 0) { newW[k] = newH[k] = 0; for (t = S[i][j]; t <= i; ++t) { /* Merge steps S[i][j] through i */ newW[k] += W[t]; newH[k] += H[t]; } i = S[i][j] - 1; --j; --k; /* Prepare for the next merging */ } } /* Funcion for a text-based drawing of the steps. This works under the assumption that the widths and heights of the steps are positive integers. The problem makes sense even if these are floating-point numbers, but then drawing the steps requires more effort. */ void drawSteps ( int n, int *W, int *H ) { char **A; int totw, toth; int i, j, s, t; printf("--- Widths : "); for (i=0; i=0; --i) { printf("%s\n", A[i]); free(A[i]); } for (i=0; i<=totw; ++i) printf("-"); printf("\n"); free(A); } int main ( int argc, char *argv[] ) { int n, m, i; int *W, *H, *W1, *H1; int **M, **T, **S; if (argc >= 3) { n = atoi(argv[1]); m = atoi(argv[2]); } else { n = NDFT; m = MDFT; } srand((unsigned int)time(NULL)); /* Generate steps */ W = (int *)malloc(n * sizeof(int)); H = (int *)malloc(n * sizeof(int)); initSteps(n,W,H); /* Compute merging costs */ M = (int **)malloc(n * sizeof(int *)); for (i=0; i