static int dp(int cur, int mask) {
      if (dp[mask][cur] > 0)
        return dp[mask][cur];
      if (mask == 0)
        return 0;
  
      int count = 0;
      for (int i = 0; i <= cur; i++)
        if ((mask & (1 << i)) > 0)
          count++;
  
      int best = Integer.MAX_VALUE;
      int newmask = mask & ~(1 << cur);
      for (int i = 0, j = 0; i < n; i++)
        if ((mask & (1 << i)) > 0) {
          j++;
          if (i == cur)
            continue;
          int translation = j > count ? j - count : count - j - 1;
         best = Math.min(best, dp(i, newmask) + translation + rotation[i][cur] + 1);
         // best = Math.min(best, dp(i, newmask) + translate(newmask, i, cur) + rotation[i][cur] + 1);
      }
  
      return dp[mask][cur] = best;
    }