爪哇,$ 806,899
这是来自2501发子弹的试验。我仍在努力对其进行优化。我写了两个类,一个包装器和一个播放器。包装器使用信封的数量实例化玩家(对于真实物品,始终为10000),然后takeQ使用顶部信封的值调用该方法。然后,true如果玩家接受,玩家将返回,false如果他们通过了则。
播放器
import java.lang.Math;
public class Player {
  public int[] V;
  public Player(int s) {
    V = new int[s];
    for (int i = 0; i < V.length; i++) {
      V[i] = i + 1;
    }
    // System.out.println();
  }
  public boolean takeQ(int x) {
    // System.out.println("look " + x);
    // http://www.programmingsimplified.com/java/source-code/java-program-for-binary-search
    int first = 0;
    int last = V.length - 1;
    int middle = (first + last) / 2;
    int search = x;
    while (first <= last) {
      if (V[middle] < search)
        first = middle + 1;
      else if (V[middle] == search)
        break;
      else
        last = middle - 1;
      middle = (first + last) / 2;
    }
    int i = middle;
    if (first > last) {
      // System.out.println(" PASS");
      return false; // value not found, so the envelope must not be in the list
                    // of acceptable ones
    }
    int[] newVp = new int[V.length - 1];
    for (int j = 0; j < i; j++) {
      newVp[j] = V[j];
    }
    for (int j = i + 1; j < V.length; j++) {
      newVp[j - 1] = V[j];
    }
    double pass = calcVal(newVp);
    int[] newVt = new int[V.length - i - 1];
    for (int j = i + 1; j < V.length; j++) {
      newVt[j - i - 1] = V[j];
    }
    double take = V[i] + calcVal(newVt);
    // System.out.println(" take " + take);
    // System.out.println(" pass " + pass);
    if (take > pass) {
      V = newVt;
      // System.out.println(" TAKE");
      return true;
    } else {
      V = newVp;
      // System.out.println(" PASS");
      return false;
    }
  }
  public double calcVal(int[] list) {
    double total = 0;
    for (int i : list) {
      total += i;
    }
    double ent = 0;
    for (int i : list) {
      if (i > 0) {
        ent -= i / total * Math.log(i / total);
      }
    }
    // System.out.println(" total " + total);
    // System.out.println(" entro " + Math.exp(ent));
    // System.out.println(" count " + list.length);
    return total * (Math.pow(Math.exp(ent), -0.5) * 4.0 / 3);
  }
}
包装纸
import java.lang.Math;
import java.util.Random;
import java.util.ArrayList;
import java.util.Collections;
public class Controller {
  public static void main(String[] args) {
    int size = 10000;
    int rounds = 2501;
    ArrayList<Integer> results = new ArrayList<Integer>();
    int[] envelopes = new int[size];
    for (int i = 0; i < envelopes.length; i++) {
      envelopes[i] = i + 1;
    }
    for (int round = 0; round < rounds; round++) {
      shuffleArray(envelopes);
      Player p = new Player(size);
      int cutoff = 0;
      int winnings = 0;
      for (int i = 0; i < envelopes.length; i++) {
        boolean take = p.takeQ(envelopes[i]);
        if (take && envelopes[i] >= cutoff) {
          winnings += envelopes[i];
          cutoff = envelopes[i];
        }
      }
      results.add(winnings);
    }
    Collections.sort(results);
    System.out.println(
        rounds + " rounds, median is " + results.get(results.size() / 2));
  }
  // stol... I mean borrowed from
  // http://stackoverflow.com/questions/1519736/random-shuffling-of-an-array
  static Random rnd = new Random();
  static void shuffleArray(int[] ar) {
    for (int i = ar.length - 1; i > 0; i--) {
      int index = rnd.nextInt(i + 1);
      // Simple swap
      int a = ar[index];
      ar[index] = ar[i];
      ar[i] = a;
    }
  }
}
完成优化后,很快就会有更详细的说明。
核心思想是能够根据给定的一组信封估算玩游戏所获得的回报。如果当前的信封集合是{2,4,5,7,8,9},而最高的信封是5,那么有两种可能性:
- 拿5和{7,8,9}一起玩游戏
 
- 通过5并玩{2,4,7,8,9}的游戏
 
如果我们计算{7,8,9}的预期奖励并将其与{2,4,7,8,9}的预期奖励进行比较,我们将能够知道服用5是否值得。
现在的问题是,给定一组像{2,4,7,8,9}这样的信封,期望值是多少?我发现期望值似乎与集合中的货币总量成正比,但与货币所分成的信封数的平方根成反比。这是由于“完美地”玩了几个小型游戏,其中所有信封的价值几乎相同。
下一个问题是如何确定“ 有效信封数”。在所有情况下,通过跟踪您所看到的内容和完成的操作,可以准确知道信封的数量。像{234,235,236}这样的东西肯定是三个信封,{231,232,233,234,235}肯定是5个信封,但是{1,2,234,235,236}应该真正算作3个而不是5个信封,因为1和2几乎一文不值,并且您永远不会在234上通过您以后可以选择1或2。我有个想法,就是使用Shannon熵来确定有效信封数。  
我将计算的目标定位为信封的值在一定时间间隔内均匀分布的情况,这就是游戏过程中发生的情况。如果我采用{2,4,7,8,9}并将其视为概率分布,则其熵为1.50242。然后,我exp()得到4.49254作为有效信封数。
来自{2,4,7,8,9}的估计报酬是 30 * 4.4925^-0.5 * 4/3 = 18.87
确切的数字是18.1167。
这不是一个精确的估计,但是当信封在一个间隔内均匀分布时,它对数据的拟合程度非常好,我实际上为此感到非常自豪。我不确定乘数是否正确(我现在使用4/3),但这是不包含乘数的数据表。
Set of Envelopes                    Total * (e^entropy)^-0.5      Actual Score
{1,2,3,4,5,6,7,8,9,10}              18.759                        25.473
{2,3,4,5,6,7,8,9,10,11}             21.657                        29.279
{3,4,5,6,7,8,9,10,11,12}            24.648                        33.125
{4,5,6,7,8,9,10,11,12,13}           27.687                        37.002
{5,6,7,8,9,10,11,12,13,14}          30.757                        40.945
{6,7,8,9,10,11,12,13,14,15}         33.846                        44.900
{7,8,9,10,11,12,13,14,15,16}        36.949                        48.871
{8,9,10,11,12,13,14,15,16,17}       40.062                        52.857
{9,10,11,12,13,14,15,16,17,18}      43.183                        56.848
{10,11,12,13,14,15,16,17,18,19}     46.311                        60.857
期望值与实际值之间的线性回归得出R ^ 2值为0.999994。
我改善该答案的下一步是在信封的数量开始变少时(即当信封的分布不均一且问题开始变得细化时)改进估计。
编辑:如果认为这值得比特币,我刚在收到了一个地址1PZ65cXxUEEcGwd7E8i7g6qmvLDGqZ5JWg。谢谢!(这是挑战作者发放奖品的时间。)