Java 列出具有约束的集合中所有可能和的总和

Java 列出具有约束的集合中所有可能和的总和,java,math,recursion,probability,expectations,Java,Math,Recursion,Probability,Expectations,我很想了解以下情况: 给定一个有N个元素的集合,我和我的朋友在玩一个游戏。我总是先发制人。 我们只能移除第一个或最后一个元素,每个元素都有50%的几率。我们在游戏中轮流进行。如果只剩下一个元素,我们可以肯定地移除它。我可以收集的预期金额是多少 For example:N=2 {10,20} Possible sets that I can collect are {10},{20}. So expected sum is 0.5*10+0.5*20=15. 我的做法: 由于得到一个可能和的概率

我很想了解以下情况:

给定一个有N个元素的集合,我和我的朋友在玩一个游戏。我总是先发制人。 我们只能移除第一个或最后一个元素,每个元素都有50%的几率。我们在游戏中轮流进行。如果只剩下一个元素,我们可以肯定地移除它。我可以收集的预期金额是多少

For example:N=2 {10,20} Possible sets that I can collect are {10},{20}.
So expected sum is 0.5*10+0.5*20=15.
我的做法:

由于得到一个可能和的概率在所有情况下都是相等的,我们只需要计算所有可能和的和,然后乘以0.5^N/2

我尝试使用递归计算所需的和:

f(i,j)-computes the sum between i and j recursively
f(i,j)=2*a[i]+func(i,j-2)+func(i+1,j-1)+func(i+1,j-1)+func(i+2,j)+2*a[j]);
Initial call f(1,N)
但这种方法似乎不起作用。我该怎么办

完整功能如下:

class CandidateCode {
    static long v[][] = new long[1003][1003];

    public static long func(int a[], int i, int j) {
        if (i == j)
            return v[i][j] = a[i];
        if (v[i][j] != 0)
            return v[i][j];
        else {
            if (i > j - 2 && i + 1 > j - 1 && i + 2 > j)
                return (v[i][j] += 2 * a[i] + 2 * a[j]);
            else
                return (v[i][j] += 2 * a[i] + func(a, i, j - 2) + func(a, i + 1, j - 1) + func(a, i + 1, j - 1)
                        + func(a, i + 2, j) + 2 * a[j]);
        }
    }

    public static void main(String args[]) {
        int n;
        int a[] = { 0, 6, 4, 2, 8 };
        n = a.length - 1;
        System.out.println(func(a, 1, 4) / Math.pow(2, n / 2));
    }
}

这个问题可以通过应用动态规划来解决

首先,游戏的状态是player,start,end,这表示当前玩家,以及原始集合中可用的值的范围。在开始时,我们从玩家0开始,开始是0,结束是N-1

表示第一个玩家是0,第二个玩家是1,我们有玩家0的期望值:

 if(player == 0){
    double result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
 }else{
     double result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
 }
因此,对于每个状态,我们可以将所有计算出的状态存储在dp[player][start][end]表中,这将时间复杂度降低到O2*N*N,其中N是集合中的数值

伪代码:

 double expectedValue(int player, int start, int end, int[]set){
       if(start == end)
          if(player == 0)
             return set[start];
          return 0;
       if(already calculated this state)
          return dp[player][start][end];
       double result= 0;
       if(player == 0){
          result = 0.5*( set[start] + f(1, start + 1,end) ) + 0.5*(set[end] + f(1,start, end - 1));
       }else{
          result = 0.5*( f(0, start + 1,end) ) + 0.5*(f(0,start, end - 1));
       }
       return dp[player][start][end] = result;
  }

NWe只能以50%的概率移除第一个或最后一个元素,这意味着在每一轮中,您可以获得第一个或最后一个元素,但始终保证获得1,就像掷硬币一样,你也可以选择,你得到你选择的东西的几率是50%?我们可以选择第一个或最后一个元素,概率是1/2。是的,我们保证每回合得到一个元素@Pham trung没有得到游戏规则,但要解决标题中提到的问题:获得所有的数字幂集,有现有的算法,然后检查每个组合的前提条件。如果它成立,计算总和。仅此而已。N=1000如何使用电源设置无法理解..你能详细说明吗?@rajarshi369在哪部分你不理解?在dp@rajarshi369我们首先从一个完整的集合开始,所以我们只能取出位置0或位置N-1处的元素,所以下一个状态只能是start+1,end或start,end-1,对吗?玩家轮流,所以玩家0->玩家1->玩家0…@rajarshi369,我们只需要关心玩家0,所以只需要在结果中添加玩家==0的值,就这样!