public BigDecimal runCarlo(int[] a) {
    String serial = serialize(a);
    if (carlodp.containsKey(serial)) {
      return carlodp.get(serial);
    }

    List<Swap> swaps = new ArrayList<Swap>();
    for (int x = 0; x < a.length - 1; x++) {
      if (a[x] > a[x + 1]) {
        swaps.add(new Swap(x, x + 1));
      }
    }
    
    if (swaps.size() == 0) {
      BigDecimal zero = new BigDecimal(0);
      carlodp.put(serial, zero);
      return zero;
    } else {
      BigDecimal expected = new BigDecimal(a.length - 1);
      expected.setScale(100);
      expected = expected.divide(new BigDecimal(swaps.size()), 100, BigDecimal.ROUND_HALF_UP);

      for (int x = 0; x < swaps.size(); x++) {
        int[] newa = a.clone();
        swap(newa, swaps.get(x).start, swaps.get(x).end);
        expected = expected.add(runCarlo(newa).divide(
            new BigDecimal(swaps.size()), 100, BigDecimal.ROUND_HALF_UP));
      }
      carlodp.put(serial, expected);
      return expected;
    }
  }