I would suggest you to reformulate your backtracking in order to use dynamic programming to trimm the backtracking tree. Here is the logic I propose to design it:
When deciding if you want or not to change a cell, it doesn't really matter how you assigned the previous cells, it only matters the accumulated cost, so you can keep track for each cell, and each possible accumulated cost, what was the minimum result already found. This way whenever you find the same configuration again, you will have the answer saved.
So your dp matrix would be something like:
dp[top_bound][n][n];
And before doing backtracking you should do:
if(dp[acc_cost][this_i][this_j] != -1)
return dp[acc_cost][this_i][this_j];
// Perform your calculations
// ...
dp[acc_cost][this_i][this_j] = result;
return result;
Here I'm assuming -1
is an invalid value in the result, if not you just choose any invalid value and initialize your matrix to it. Since this matrix is of size n*n*top_bound, then a correctly implemented DP should solve the problem in O(n*n*top_bound).